2014-03-24 132 views
1

我是新來的ASM,我試圖創建一個基本的Hello World程序,使用函數:ASM x86_64的Hello World程序

section .text 
    global main 

print_msg: 

    push rbp 
    mov rbp, rsp 

    mov rax, 1 
    mov rdi, 1 
    mov rsi, Buffer  ;to change 
    mov rdx, BufferSize ;to change 
    syscall 

    mov rsp, rbp 
    pop rbp 

    ret 

main: 

    mov rdi, Buffer 
    mov rsi, BufferSize 
    call print_msg 

    mov rax, 60 
    mov rdi, 0 
    syscall 

section .rodata 

Buffer:  db 'Hello, world !', 0x0A 
BufferSize: equ $-Buffer 

此代碼實際工作,但僅僅是因爲我直接複製緩衝區在RDX RSI及緩衝區大小,在我的「print_msg」的功能,但我想接收arguements於這兩個寄存器複製,我看到的東西,如:

mov rsi, [rsp + 8] 
mov rdx, [rsp + 12] 

但它不會在這裏工作。

回答

2

x86-64的使用寄存器來傳遞參數,因爲你的代碼也說明:

mov rdi, Buffer 
mov rsi, BufferSize 
call print_msg 

如果您加載rdirsi的論據,你爲什麼希望他們在被調用函數的棧? CALL不對寄存器做任何事情,只將返回地址放在堆棧上。因此,你的兩個論點在rdirsi中仍然很開心。只是mov他們到了正確的地方:

mov rdx, rsi 
mov rsi, rdi 
mov rax, 1 
mov rdi, 1 
syscall 
1

你可以;您需要在通話之前推送參數。像這樣:

push Buffer 
push BufferSize 
call print_msg 
add rsp, 16 

然後他們變得可以訪問[rbp + 16],[rbp + 24]。但這是一個糟糕的主意。通常接受的x86_64調用約定要求在寄存器中傳遞前幾個參數。在Linux上,這是RDI,RSI,RDX,RCX,R8和R9。所以只要你不重置函數內的RSI和RDI(就像你現在做的那樣),你就很好。