Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 从64位asm调用Printf时如何传递参数?_Assembly_Printf_X86 64_Calling Convention_Abi - Fatal编程技术网

Assembly 从64位asm调用Printf时如何传递参数?

Assembly 从64位asm调用Printf时如何传递参数?,assembly,printf,x86-64,calling-convention,abi,Assembly,Printf,X86 64,Calling Convention,Abi,我正在再次学习汇编语言,到目前为止,我唯一的问题就是调用C语言。我的书是32位的,我是64位的。显然,在通话习惯上有很大的不同,而且网站已经关闭了。因此,经过一些挖掘/测试,用C语言编译虚拟程序,并花了3天时间在这上面,我想如果我的发现对其他人有帮助的话,我会发布我的发现 是否需要为RAX提供浮点计数? 堆栈填充“阴影空间”是16位还是32位? 对于小程序来说,这个用于对齐堆栈的宏可以通过吗?我知道你不能用align填充代码,我不确定堆栈框架 ; pf.asm compiled with 'na

我正在再次学习汇编语言,到目前为止,我唯一的问题就是调用C语言。我的书是32位的,我是64位的。显然,在通话习惯上有很大的不同,而且网站已经关闭了。因此,经过一些挖掘/测试,用C语言编译虚拟程序,并花了3天时间在这上面,我想如果我的发现对其他人有帮助的话,我会发布我的发现

是否需要为RAX提供浮点计数? 堆栈填充“阴影空间”是16位还是32位? 对于小程序来说,这个用于对齐堆栈的宏可以通过吗?我知道你不能用align填充代码,我不确定堆栈框架

; pf.asm compiled with 'nasm -o pf.o -f elf64 -g -F stabs'
; linked with 'gcc -o pf pf.o'
; 64-bit Bodhi (ubuntu) linux

%include "amd64_abi.mac"
[SECTION .data]
First_string:   db "First string.",10,"%s", "%d is an integer. So is %d",10
                db "Floats XMM0:%5.7f  XMM1:%.6le  XMM2:%lg",10,0  
Second_String:  db "This is the second string... %s's are not interpreted here.",10
                db " Neither are %d's nor %f's. 'Cause it is a passed value.", 10, 0
; Just a regular string for insert.
[SECTION .bss]
[SECTION .text]
EXTERN printf
GLOBAL main
main:
_preserve_64AMD_ABI_regs ; Saves RBP, RBX, R12-R15
mov rdi, First_string   ; Start of string to be formatted. Null terminated
mov rsi, Second_String  ; String addy of first %s in main string. Not interpretted
mov rcx, 0456           ; Second Integer (Register is specific for ordered arguments.)
mov rdx, 0123           ; First integer (Order of assignment does not matter.)
                        ; Order of Integer/Pointer Registers:
                        ; $1:RDI   $2:RSI   $3:RDX   $4:RCX   $5:R8   $6:R9

mov rax,0AABBCCh         ; Test value to be stored in xmm0
cvtsi2sd xmm0, rax      ; Convert quad to scalar double
mov rax,003333h         ; Test value to be stored in xmm1
cvtsi2sd xmm1, rax      ; Convert quad to scalar double
cvtsi2sd xmm2, rax      ; Convert quad to scalar double
divsd xmm2, xmm0        ; Divide scalar double

sub rsp, 16             ; Allocates 16 byte shadow memory
_prealign_stack_to16    ; Move to the lower end 16byte boundry (Seg-Fault otherwise)
;    mov rax, 3             ; Count of xmm registers used for floats. ?!needed?!
Before_Call:
call printf             ; Send the formatted string to C-printf
_return_aligned_stack   ; Returns RSP to the previous alignment
add rsp, 16             ; reallocate shadow memory

_restore_64AMD_ABI_regs_RET
; Ends pf.asm

; amd64_abi.mac
; Aligns stack (RSP) to 16 byte boundry, padding needed amount in rbx
%macro _preserve_64AMD_ABI_regs 0
push rbp
mov rbp, rsp
push rbx
push r12
push r13
push r14
push r15
%endmacro

%macro _restore_64AMD_ABI_regs_RET 0
pop r15
pop r14
pop r13
pop r12
pop rbx
mov rsp, rbp
pop rbp
ret
%endmacro

%macro _prealign_stack_to16 0
mov rbx, 0Fh            ; Bit mask for low 4-bits 10000b = 16 :: 01111b = 15b
and rbx, rsp            ; get bits 0-3 into rbx
sub rsp, rbx            ; remove them from rsp, rounding down to multiple of 16 (10h)
%endmacro

; De-aligns stack (RSP)from 16 byte boundry using saved rbx offset
%macro _return_aligned_stack 0
add rsp, rbx
%endmacro
输出: 第一串。 这是第二个字符串…%这里不解释。 %d和%f都不是因为它是一个传递的值。 123是一个整数。456也是 浮动XMM0:11189196.0000000 XMM1:1.310700e+04 XMM2:0.0011714

资源: System V ABI v0.96:(在x86-64.org网站上不可用,网站关闭) 一步一步地使用汇编语言。杰夫·邓特曼第12章 英特尔64位指令集

是的,
RAX
(实际上是
AL
)应该包含使用的
XMM
寄存器的数量

堆栈对齐代码过于复杂,通常只需执行
和rsp,-16
。此外,通常只进行一次堆栈对齐(通常在
main
的开头),然后通过始终适当调整
rsp
来保持堆栈对齐

SYSV ABI不使用阴影空间(这是微软的惯例),而是使用“红色区域”,但这并不影响调用顺序

更新关于堆栈对齐:

在已经对齐的函数
RSP
(通常除了
main
)中,您只需确保所有调用的函数依次获得更改了16倍的
RSP

如果您使用的是标准帧指针,那么您的函数以一个
PUSH RBP
开始,因此您只需确保以16的倍数分配空间(如果需要),如下所示:

push-rbp
mov rbp,rsp
副rsp,n*16
...
mov rsp,rbp
流行限制性商业惯例
ret
否则,您将不得不补偿堆栈上的8字节
RIP
(正如您在评论中正确指出的):

只有在调用其他函数时,上述两种方法才适用,也就是说,在叶函数中,您可以做任何您想做的事情。此外,我前面提到的红色区域在叶函数中很有用,因为您可以在堆栈指针下使用128字节,而无需显式分配,这意味着您根本不必调整
RSP

; in leaf functions you can use memory under the stack pointer
; (128 byte red zone)
mov [rsp-8], rax

显而易见的方法是先用C编写代码,然后由C编译器生成程序集。它永远不会错。很好,这很有帮助。所以,当我在初始对齐后推动时,按如下所示进行操作;亚rsp,10小时;移动值[rsp],$value。。。然后在通话结束后再加回去?所有通话都会在通话前对齐到16,对吗?然后调用将RIP推到堆栈上。让它需要调整8。。。因此,我可以在开始时和
rsp,-16
,然后在RET之前添加rsp,8。对吗?
; in leaf functions you can use memory under the stack pointer
; (128 byte red zone)
mov [rsp-8], rax