Mar*_*tin 7 c x86 assembly gcc inline-assembly
我无法编译从教程中获取的程序.它应该打印"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\""
);
}
Run Code Online (Sandbox Code Playgroud)
gcc 4.7 在Linux下给我以下错误:
gcc hello.c -o hello
hello.c: Assembler messages:
hello.c:5: Error: invalid instruction suffix for `pop'
Run Code Online (Sandbox Code Playgroud)
还有一种方法可以避免为每一行指定双引号吗?
另外,我想知道如何修改程序以使用libc调用printf而不是kernel服务.
Nay*_*uki 10
问:
hello.c: Assembler messages:
hello.c:5: Error: invalid instruction suffix for `pop'
Run Code Online (Sandbox Code Playgroud)
答:popl在x86-32上可用,但在x86-64上没有(popq相反).您需要调整汇编代码以使用x86-64,或者需要调用GCC来生成x86-32二进制输出.
假设您要生成x86-32,请使用命令行选项-m32.
问:
还有一种方法可以避免为每一行指定双引号吗?
答:没有.这是因为__asm__()是一个伪函数,它接受字符串参数,所以字符串遵循C语法.字符串的内容在很少或没有处理的情况下传递给汇编程序.
请注意,在C中,当并置字符串时,它们会连接在一起.例如,"a" "b"与...相同"ab".
请注意,在汇编语言语法(GAS)中,您可以按换行符或分号分隔语句,如下所示:"movl xxx; call yyy"或"movl xxx \n call yyy".
问:
如何修改程序使用libc调用
printf
答:遵循x86上C的调用约定.从右到左推送参数,调用函数,然后清理堆栈.例:
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 */
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
826 次 |
| 最近记录: |