ASM x86_64 Hello world程序

时间:2014-03-24 14:25:27

标签: assembly x86 nasm x86-64

我是ASM的新手,我正在尝试使用函数创建一个基本的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

这段代码实际上有效,但只是因为我直接在我的“print_msg”函数中复制了rdx中的rsi和BufferSize中的Buffer,但是我想在这两个寄存器中复制收到的争论,我看到了类似的东西:

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

但它在这里不起作用。

2 个答案:

答案 0 :(得分: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 :(得分: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(就像你现在那样),你就会很好。