【问题标题】:Assembly: printf not printing new line装配:printf 不打印新行
【发布时间】:2016-08-11 00:16:21
【问题描述】:

我有以下代码打印传递给./main 的参数数量。请注意rodata 部分中的fmt。我已经包含了新行 \n,就像在 C 中一样,但不是打印新行,而是打印:

参数个数:1 \n

我的代码是:

;main.asm
GLOBAL main
EXTERN printf

section .rodata:
fmt db "Number of parameters: %d \n", 0 

section .text:

main:

    push ebp
    mov ebp, esp    ;stackframe

    push dword[ebp+8]       ;prepara los parametros para printf
    push fmt
    call printf
    add esp, 2*4

    mov eax, 0      ;return value

    leave           ;desarmado del stack frame
    ret

我知道在 fmt 中的 0 之前和“数字...”之后包含 10 会打印它,但我希望 printf 这样做。我用 NASM 组装代码,然后通过 GCC 链接它来创建我的可执行文件。

【问题讨论】:

  • 你不会像那样“编译”汇编器代码,而是使用 assembler。而且您不会“编译”生成的目标文件,而是 link 它。无论如何,这与 gcc 无关,也绝对与 C 语言无关。不要添加不相关的标签。

标签: linux assembly x86 printf nasm


【解决方案1】:

汇编器不是 C。C 编译器将 \n 理解为 ASCII 10 的转义码。汇编器不会并将其视为两个字符。按照您的描述添加 10 个。

【讨论】:

    【解决方案2】:

    当您在 NASM 中的字符串周围使用引号或双引号时,它不接受 C 样式的转义序列。在 Linux 上,您可以像这样将 \n 编码为 ASCII 10:

    fmt db "Number of parameters: %d", 10, 0 
    

    还有一个选择。 NASM 支持反引号(反引号),这将允许 NASM 将它们之间的字符处理为 C 样式的转义序列。这也应该有效:

    fmt db `Number of parameters: %d \n`, 0
    

    请注意:这些不是单引号,而是反引号。这在NASM documentation 中有描述:

    3.4.2 字符串

    一个字符串最多包含八个字符,分别用单引号 ('...')、双引号 ("...") 或反引号 (...) 括起来。单引号或双引号等价于 NASM(当然,用单引号括起来的常量允许双引号出现在其中,反之亦然);这些内容逐字呈现。 用反引号括起来的字符串支持特殊字符的 C 样式转义

    【讨论】:

    • 请注意,YASM 版本的 NASM 语法不支持反引号引用的字符串文字。我不认为 YASM 有办法用转义序列编写字符串常量。这只在您关心 yasm 以及官方 nasm 本身时才重要。
    • @PeterCordes :最后一段中的原始问题说NASM,我的答案是NASM。如果我指的是 YASM,我会这样说。 YASM 不是 NASM,就像 TASM 不是 MASM.. 如果问题是关于 GAS , YASM, MASM 语法(和其他变体,其中一些共享某些功能而不是其他)我会提供一个涵盖它们的答案。如果您想提供一个涵盖市场上所有汇编程序和变体的答案,请来找我。
    • 我并没有声称您的答案不完整,或者您应该提到它。我只是觉得这是一个有趣的补充,因为 YASM 几乎完全兼容 NASM 语法。
    猜你喜欢
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    相关资源
    最近更新 更多