嗨,我还是使用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("%dn", a);
}
这与指针错误有关吗?
除了注释中指出的其他错误外,这里还有一个重要问题:
"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;"
考虑程序流程。您的C代码属于此程序集代码。汇编代码调用自己的内部函数(不是问题),然后返回到调用前的指令。。。还是没问题。一个值被移动到EAX。。。然后你通过你的函数返回。这太糟糕了。
通过使用ret
,您绕过了整个C函数的epilog。这意味着没有正确清理堆栈,也没有恢复堆栈。这几乎肯定会导致崩溃。