【问题标题】:Printing a number in assembly NASM using printf使用 printf 在汇编 NASM 中打印一个数字
【发布时间】:2015-09-17 13:01:57
【问题描述】:

我一直试图让它打印 12345 有一段时间了。任何人都可以提供关于我应该做什么的提示吗?它将打印三行文本,然后在第四行打印“年龄”,我猜这是第 2 行堆栈中的剩余部分。

    bits 64
    global main
    extern printf

    section .text
main:
    ; function setup
    push    rbp
    mov     rbp, rsp
    sub     rsp, 32
    ;
    lea     rdi, [rel message]
    mov     al, 0
    call    printf
;above code correctly prints message

;where the issue lies
push rbp
mov rbp, rsp
;sub rsp, 32

mov rax, 12345
;push rax   
mov al,0
call printf


    ; function return
    mov     eax, 0
    add     rsp, 32
    pop     rbp
    ret

    section .data
message: db      'Lab 3 - Modified Hello program',0x0D,0x0a,'COSC2425 - Pentium assembly language',0x0D,0x0a,'Processed with NASM and GNU gcc',0x0D,0x0a
count   dq  12345

【问题讨论】:

    标签: assembly printf nasm x86-64 calling-convention


    【解决方案1】:

    显然你甚至不知道printf 是如何工作的,这使得很难从程序集中调用它。

    要打印一个数字,printf 需要两个参数,一个格式字符串和要打印的数字。示例:printf("%d\n", 12345)

    现在要将其转换为汇编,您显然需要声明该格式字符串,然后使用适当的约定传递两个参数。

    由于您似乎在使用 sysv abi,​​这意味着前两个参数分别进入 rdirsi。您似乎已经知道必须将 al 归零以表示未使用 SSE 寄存器。因此,相关部分可能如下所示:

    lea rdi, [rel fmt]
    mov rsi, 12345 ; or mov rsi, [count]
    mov al, 0
    call printf
    ...
    fmt: db "%d", 0x0a, 0
    

    【讨论】:

    • 这门课将是我的死亡。在作业中,它说用 12345 加载 rax。通过电子邮件寻求帮助,他说那是错误的。这几天我一直在想办法解决这个问题。它现在打印 9012345。任何想法为什么?它与我如何将字符串发送到 printf 有关
    • 您的代码看起来如何?我在回答中显示的内容很好。您必须将rsi 中的号码传递给printf,没有办法。如果你坚持,你可以mov rax, 12345; mov rsi, rax 但这当然很傻。
    • 我的代码如上,但与您的 print 12345 版本有关。它与 print message 部分有关。我必须将 12345 增加 2 并将其移回 rsi 寄存器(他在作业中说 rax)并使用完全相同的代码位来打印新数字。打印时没有 90。在打印数字之前肯定是字符串部分。我会努力弄清楚的!谢谢!
    • 哦该死的,应该补充一下,对不起!接得好!需要将其添加到所有字符串的末尾,包括格式(更新答案)。一些汇编器具有自动执行此操作的特殊指令。
    猜你喜欢
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 2011-10-17
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多