【问题标题】:ASM x86_64 Hello world programASM x86_64 Hello world 程序
【发布时间】:2014-05-01 23:22:01
【问题描述】:

我是 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]

但在这里不起作用。

【问题讨论】:

    标签: assembly x86 nasm x86-64


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案2】:

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

      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(就像您现在所做的那样),就可以了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-21
        • 2015-05-04
        • 2014-08-16
        • 2014-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多