2013-05-07 101 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

相關問題