Assembly ASM x86_64 Hello world计划

Assembly ASM x86_64 Hello world计划,assembly,x86,nasm,x86-64,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 r

我是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”函数中直接复制了rsi中的Buffer和rdx中的BufferSize,但我想复制这两个寄存器中接收到的参数,我看到了如下内容:

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

但它在这里不起作用。

x86-64使用寄存器传递参数,正如您的代码所示:

 mov rdi, Buffer
 mov rsi, BufferSize
 call print_msg
如果加载了带有参数的
rdi
rsi
,为什么希望它们位于被调用函数的堆栈上
CALL
对寄存器不做任何操作,只将返回地址放在堆栈上。因此,您的两个参数仍然在
rdi
rsi
中运行良好。只需将它们移动到正确的位置:

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

你可以;您需要在调用之前推送参数。像这样:

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(就像你现在做的那样),你就很好