【发布时间】:2018-11-11 16:27:19
【问题描述】:
如果我在 Windows x86 上使用 GCC 编译器编译它,我有以下程序(AT&T 汇编语法)可以完美运行:
LC0:
.ascii "Hello, world!\0"
.globl _main
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $LC0, (%esp)
call _puts
movl $0, %eax
leave
ret
这个简单的程序可以在 C 程序中执行吗?我尝试了以下方法:
#include <stdlib.h>
int main()
{
__asm__ ("LC0:\n\t"
".ascii 'Welcome Message\0'\n\t"
"LC1:\n\t"
".ascii 'Hello\0'\n\t"
"_main:\n\t"
"LFB11:\n\t"
"leal 4(%esp), %ecx\n\t"
"andl $-16, %esp\n\t"
"pushl -4(%ecx)\n\t"
"pushl %ebp\n\t"
"movl %esp, %ebp\n\t"
"pushl %ecx\n\t"
"subl $20, %esp\n\t"
"call ___main\n\t"
"movl $1, 12(%esp)\n\t"
"movl $LC0, 8(%esp)\n\t"
"movl $LC1, 4(%esp)\n\t"
"movl $0, (%esp)\n\t"
"call _MessageBoxA@16\n\t"
"subl $16, %esp\n\t"
"movl $0, %eax\n\t"
"movl -4(%ebp), %ecx\n\t"
"leave\n\t"
"leal -4(%ecx), %esp\n\t"
"ret\n\t");
return 0;
}
我得到一个错误:
错误:行尾有垃圾,第一个无法识别的字符是 `8'
【问题讨论】:
-
@Someprogrammerdude GCC 没有内联汇编程序。 GCC 对您的内联程序集进行文本替换并将其粘贴到自己的程序集输出中。也就是说,clang 确实有一个不理解某些结构的内联汇编程序。
-
这不是minimal reproducible example,因为您的代码甚至不包含您的错误消息所抱怨的字符
8。您究竟是如何在全局范围内对包含__asm__语句的文件运行编译器的?为什么还要将 asm 放在全局范围而不是单独的.s文件中? -
嵌入的
'\0'可能会导致问题。您可能想尝试像"\\0"一样逃避它。或者改用.asciiz指令。 -
Junk at the end of the line 意味着有... junk 在行尾。检查行尾的隐藏或无意义的字符。
-
而为什么你还想做这样的事情?将某些程序集直接复制到 C 函数中的目的是什么?为什么不能将汇编文件保持原样并使用它而不是将代码包装在 C 函数中?
标签: c gcc assembly inline-assembly