简体   繁体   English

如何用内联asm编译这个程序?

[英]How to compile this program with inline asm?

I cannot compile this program taken from a tutorial. 我无法编译从教程中获取的程序。 It should print "Hello World". 它应该打印“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 under Linux gives me the following error: Linux下的gcc 4.7给出了以下错误:

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

Is there also a way to avoid to specify double quotes for each line? 还有一种方法可以避免为每一行指定双引号吗?

Also, I'd like to know how to modify the program to use libc call printf instead of the kernel service. 另外,我想知道如何修改程序以使用libc调用printf而不是kernel服务。

Q :

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

A : popl is available on x86-32 but not on x86-64 (it has popq instead). popl在x86-32上可用,但不在x86-64上(它有popq )。 You need to either adapt your assembly code to work on x86-64, or you need to invoke GCC to generate x86-32 binary output. 您需要调整汇编代码以使用x86-64,或者需要调用GCC来生成x86-32二进制输出。

Assuming you want to generate x86-32, use the command-line option -m32 . 假设您要生成x86-32,请使用命令行选项-m32

Q :

Is there also a way to avoid to specify double quotes for each line? 还有一种方法可以避免为每一行指定双引号吗?

A : Nope. :没有。 This is because __asm__() is a pseudo-function that takes string arguments, so the string follows the C syntax. 这是因为__asm__()是一个伪函数,它接受字符串参数,因此该字符串遵循C语法。 The contents of the string are passed to the assembler with little or no processing. 字符串的内容在很少或没有处理的情况下传递给汇编程序。

Note that in C, when strings are juxtaposed, they are concatenated. 请注意,在C中,当并置字符串时,它们会连接在一起。 For example, "a" "b" is the same as "ab" . 例如, "a" "b""ab"相同。

Note that in the assembly language syntax (GAS), you can separate statements by newline or by a semicolon, like this: "movl xxx; call yyy" or "movl xxx \\n call yyy" . 请注意,在汇编语言语法(GAS)中,您可以按换行符或分号分隔语句,如下所示: "movl xxx; call yyy""movl xxx \\n call yyy"

Q :

how to modify the program to use libc call printf 如何修改程序使用libc调用printf

A : Follow the calling convention for C on x86 . :遵循x86上C调用约定 Push arguments from right to left, call the function, then clean up the stack. 从右到左推送参数,调用函数,然后清理堆栈。 Example: 例:

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 */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM