【问题标题】:Passing arguments for external functions in x86-64 NASM [duplicate]在 x86-64 NASM 中为外部函数传递参数 [重复]
【发布时间】:2020-06-07 19:42:59
【问题描述】:

在 x86-32 中,您将 push 参数传递给堆栈,而在 x86-64 中,它还使用一些特定的寄存器,并且仅在堆栈之后使用。也就是说,我不明白为什么在尝试打印整数时得到Segmentation faultka 未使用):

    global _main
    extern _printf
    section .data
format:  db "%d"
b:  dw 10
blen: equ $-b
lenlen: equ $-blen
k:  dw 6
    section .bss
a:  resw 1
    section .text
_main:
    sub rsp, 8
    mov rax, 0
    mov rdi, format
    mov rsi, b
    call _printf
    mov rax, 0x2000001
    mov rdi, 0
    syscall

【问题讨论】:

  • 你也忘了设置rdirax
  • @JosephSible-ReinstateMonica 谢谢,现在它可以工作了,但打印的是 8210 而不是 10。可能它与地址有关(尽管它一直打印8210,但它不会改变),但我不明白为什么我不能在这里使用lealea rsi, [b] 让我@987654334 @)。我也设置了rdirax,我忘了更新问题。
  • @JosephSible-ReinstateMonica 你能解释一下为什么人们声明像msg: db "Hello World!", 10, 0 这样的变量吗?我不明白100 是干什么用的,我找不到有关它的信息。也许它已经连接了。
  • 10 表示 \n0 是 NUL 终止符
  • stdout 是行缓冲的。使用原始的_exit 系统调用,您可以在不以换行符结尾的 printf 之后退出而不给 stdio 更改刷新缓冲区。 Using printf in assembly leads to an empty ouput。不要那样做;如果调用 printf,则通过从 libc 调用 exit(3) 退出。 (或者,如果您正在编写 main 而不是 _start,则从 main 返回)

标签: macos assembly x86-64 nasm


【解决方案1】:

在这种情况下,printf 需要 2 个参数,一个指向格式字符串 (rdi) 的指针和一个值 (rsi)。


这可能需要:

default  rel                   ; make [format] be [rel format] by default
format  db      "%d", 0        ;the 0 terminates the C string

;       ...
        lea     rdi, [rel format]  ; put format address in first arg reg
        movsx   esi, word [b]      ; load a value from b, not its address

您只定义了一个值为 10 的单词,因此使用 movsx 将其符号扩展为 dword(或使用 movzx 进行零扩展)以获得 32 位 int 以匹配 %d 格式字符串。

如果您想要打印带有mov rsi, b 的指针作为绝对地址,您可以使用"%p", 0

【讨论】:

  • 所以我应该放在rdi "%s"?
  • paste.org/106489 — 仍然不起作用。还有"%d"
  • @JosephSible-ReinstateMonica macOS 有什么替代品吗?我只找到了 MASM。
  • @JosephSible-ReinstateMonica 哦等等,实际上是 NASM。我正在使用 NASM。 MASM 适用于 Windows。
  • @AlexeiSavitsky - 我更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 2018-01-19
  • 2012-02-10
  • 2015-12-31
  • 2020-07-20
  • 2023-03-16
  • 1970-01-01
  • 2019-02-12
  • 2018-06-06
相关资源
最近更新 更多