我是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]
但它在这里不起作用。
答案 0 :(得分:2)
x86-64使用寄存器传递参数,因为您的代码也说明了:
mov rdi, Buffer
mov rsi, BufferSize
call print_msg
如果您使用参数加载rdi
和rsi
,为什么您希望它们在被调用函数的堆栈中? CALL
不对寄存器执行任何操作,只将返回地址放在堆栈上。因此,您的两个论点仍然在rdi
和rsi
中。只需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(就像你现在那样),你就会很好。