【问题标题】:How to compile this program with inline asm?如何用内联 asm 编译这个程序?
【发布时间】:2013-08-12 01:59:08
【问题描述】:

我无法编译这个取自教程的程序。它应该打印“Hello World”。

void main() 
{
    __asm__("jmp forward\n\t"
            "backward:\n\t"
            "popl   %esi\n\t"
            "movl   $4, %eax\n\t"
            "movl   $2, %ebx\n\t"
            "movl   %esi, %ecx\n\t"
            "movl   $12, %edx\n\t"
            "int    $0x80\n\t"
            "int3\n\t"
            "forward:\n\t"
            "call   backward\n\t"
            ".string \"Hello World\\n\""
           );
}

gcc 4.7在Linux下给我以下错误:

gcc hello.c -o hello
hello.c: Assembler messages:
hello.c:5: Error: invalid instruction suffix for `pop'

还有没有办法避免为每一行指定双引号?

另外,我想知道如何修改程序以使用libc 调用printf 而不是kernel 服务。

【问题讨论】:

  • 好吧,它应该是int main,因为asm非常依赖于系统,因此它肯定会崩溃,具体取决于您使用的计算机
  • 看起来您正在编译 x86-32 代码以输出到 x86-64 二进制文件。
  • 您可以删除ls 并将%e* 更改为%r*,这样就可以到达某个地方。但是,不要相信我对此的看法。
  • @NayukiMinase 也许你应该发布一个答案,这样我们就可以投票了
  • 不要误以为在 GCC 内联汇编中使用 call 指令是一件简单的事情。除非你非常非常小心,否则有很多极端情况(尤其是在 64 位中)这样做会破坏事情。并非总是...只是有时...如果是这样,通常不会出现在您的内联汇编结束的地方。如果您这样做,clobber 列表 是必需的。

标签: c gcc assembly x86 inline-assembly


【解决方案1】:

hello.c: Assembler messages:
hello.c:5: Error: invalid instruction suffix for `pop'

Apopl 在 x86-32 上可用,但在 x86-64 上不可用(取而代之的是 popq)。您需要调整您的汇编代码以在 x86-64 上工作,或者您需要调用 GCC 来生成 x86-32 二进制输出。

假设您要生成 x86-32,请使用命令行选项 -m32

还有没有办法避免为每一行指定双引号?

A:不。这是因为__asm__() 是一个接受字符串参数的伪函数,所以字符串遵循 C 语法。字符串的内容被传递给汇编程序,几乎没有处理。

请注意,在 C 语言中,当字符串并列时,它们会被连接起来。例如,"a" "b""ab" 相同。

请注意,在汇编语言语法 (GAS) 中,您可以使用换行符或分号分隔语句,例如:"movl xxx; call yyy""movl xxx \n call yyy"

如何修改程序使用libc调用printf

A:关注calling convention for C on x86。从右向左推送参数,调用函数,然后清理堆栈。示例:

pushl $5678  /* Second number */
pushl $1234  /* First number */
pushl $fmtstr
call printf
addl $12, %esp  /* Pop 3 arguments of 4 bytes each */

/* Put this away from the code */
fmtstr: .string "Hello %d %d\n"  /* The \n needs to be double-backslashed in C */

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    相关资源
    最近更新 更多