2013-05-07 102 views
5

我正在学习再次使用汇编语言,到目前为止,我唯一遇到的问题是对C进行调用。我拥有的这本书面向32位,而我正在使用64位。显然,调用约定存在很大差异,并且http://www.x86-64.org/documentation网站已关闭。因此,经过一些挖掘/测试,在C编译虚拟程序并花费3天时间,我想我会发布我的发现,如果它可以帮助其他人。从64位asm调用printf时如何传递参数?

RAX是否需要浮点数? 堆栈填充“阴影空间”16或32位? 这个宏是否适合小程序对齐堆栈?我知道你可以用对齐方式NOP-填充代码,我不确定堆栈帧。

; 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,; 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 

输出: 第一个字符串。 这是第二个字符串...%s在这里没有解释。 %d和%f都不是。因为这是一个传递的价值。 123是一个整数。所以是456 花车XMM0:11189196.0000000 XMM1:1.310700e + 04 XMM2:0.0011714

资源: System V的ABI v0.96:http://www.uclibc.org/docs/psABI-x86_64.pdf(这是不提供x86-64.org网站已关闭) 汇编语言一步步。 Jeff Duntemann第12章 Intel 64位指令集。 http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html

+2

最明显的方法先用C编写代码,然后用C编译器生成程序集。它永远不会错。 – 2013-05-07 15:55:43

回答

6

是的,RAX(实际上AL)应该保留使用的寄存器数XMM

您的堆栈对齐代码过于复杂,通常您只是做AND rsp, -16。另外,堆栈对齐通常只进行一次(通常在main开始处),然后通过适当调整rsp来维护堆栈对齐。

SYSV ABI不使用阴影空间(这是微软约定),而是使用“红色区域”,但这不影响调用序列。

更新约栈对齐:

在已经得到对准RSP(通常一切,除了main)功能,你只要确保反过来任何调用的函数得到RSP是正通过16

的倍数变化

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

push rbp 
mov rbp, rsp 
sub rsp, n*16 
... 
mov rsp, rbp 
pop rbp 
ret 

否则,你就必须补偿8个字节的RIP放在堆栈上(如你正确地指出了这一点您的评论):

sub rsp, n*16+8 
... 
add rsp, n*16+8 
ret 

以上两者如果只调用应用其他功能,即叶功能,你可以做任何你想做的事情。此外,我前面提到的红色区域是在叶函数中很有用,因为你可以使用128个字节的堆栈指针下没有明确的分配,这意味着你不必调整RSP都:

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

不错,这是非常有帮助的。因此,无论何时,我都会在初始对齐后进行操作,将其作为; sub rsp,10h; mov [rsp],$ value ...然后在通话后将其添加回来? – DouglasCodes 2013-05-07 17:36:49

+0

在通话权之前所有通话都将对齐到16位?那么这个呼叫将RIP推入堆栈。离开它需要调整8 ...所以我可以在开始时与'rsp,-16'和在RET之前的'add rsp,8'。正确? – DouglasCodes 2013-05-07 19:22:09

+0

更新了答案。 – Jester 2013-05-07 23:00:16

相关问题