【发布时间】:2016-03-29 01:36:43
【问题描述】:
您好,我还是使用 gcc 编译器的汇编语言的新手,现在我正在研究函数。
我的程序向用户询问 4 个int 值,将这些值存储在寄存器eax、ebx、ecx 和edx 中,然后调用一个函数进行除法(ebx/eax)。我在除法后存储“d”的值,因为据我了解idiv 使用edx 来存储残差。然后它减去 (eax-ecx) 并乘以 (eax*edx),然后返回寄存器 eax 内的值。出于某种原因,我遇到了分段错误:11。
这是我的代码:
#include <stdio.h>
int a, b, c, d;
int main (void)
{
printf("Dame a: ");
scanf("%d", &a);
printf("Dame b: ");
scanf("%d", &b);
printf("Dame c: ");
scanf("%d", &c);
printf("Dame d: ");
scanf("%d", &d);
__asm( ".intel_syntax noprefix;"
"xor eax, eax;"
"mov eax, dword ptr [_a];"
"xor ebx, ebx;"
"mov ebx, dword ptr [_b];"
"xor ecx, ecx;"
"mov ecx, dword ptr [_c];"
"Call fun1;"
"mov dword ptr [_a], eax;"
"fun1: xor edx, edx;"
"idiv ebx;"
"sub eax, ecx;"
"mov edx, dword ptr [_d];"
"imul eax, edx;"
"ret;"
".att_syntax");
printf("%d\n", a);
}
是不是跟指针错误有关?
【问题讨论】:
-
没有从 C 代码调用的函数。这看起来像是错误集成的汇编代码。你认为这如何执行?您没有将 C 变量正确传递给汇编程序代码,没有列出任何破坏者等。请阅读必须如何使用内联汇编程序。
-
另外,在 inline asm 中切换语法是个坏主意。如果您想要 intel 语法 asm,请使用
gcc -masm=intel。 PS:你的执行落入fun1,然后第二次命中的ret将退出main(如果你幸运,否则它会崩溃)。 -
嗨 Jester 感谢您的回答,我知道在内联 asm 中切换语法是不好的做法,由于某种原因,如果我不这样做,我会得到 64 不支持 32 位绝对寻址-位模式错误。
-
我很惊讶即使使用 intel 语法也能编译。如果您真的要为 64 位编译,那么除了所有其他评论之外,我可能会使用 RIP 寻址。例如,我将
dword ptr [_a]编码为[rip+_a]。在 AT&T 语法中,_a(%rip)