C与汇编链接程序问题:除数判定错误及余数返回异常
问题分析与修正
核心错误点
1. 全局变量内存越界导致符号判断异常
汇编代码中修改全局变量g时,使用了QWORD PTR g[rip], 0,但g是C语言中的int类型(4字节),QWORD对应8字节,写入操作会超出g的内存范围,破坏相邻变量数值,进而出现所有输入都被判定为负数的问题。
2. 余数传递逻辑错误
- 汇编中修改的
rsi是函数参数的副本(传值调用),无法影响主程序里的static int y,因此主程序打印的余数始终是初始值100。 - 用64位寄存器处理32位整数除法,不符合C语言
int类型的位宽要求,可能引发不必要的符号扩展或计算偏差。
3. 头文件拼写错误
linkage.h中#define LINAGE_H_是笔误,应为#define LINKAGE_H_,否则无法正确阻止头文件重复包含。
修正后的代码
linkage.c
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include "linkage.h" int g = 1; int x; static int y = 100; int main() { printf("This is a very simple program, we're going to be dividing 100 by an integer provided.\n"); printf("Please make sure to provide a positive integer, I may be a machine but I still don't like negativity!\n"); printf("Please input your number:\n"); scanf("%d", &x); printf("You entered: %d\n", x); int z = divide(x, y); if (g == 0 ) { printf("You entered a negative number and I don't appreciate it!\n"); } else { printf("The quotient of your operation is %i, and the remainder is %i.\n", z, y); } return 0; }
assembly.s
.intel_syntax noprefix .global divide .extern g .extern y divide: cmp edi, 0 jge positive jmp negative positive: mov eax, esi xor edx, edx div edi mov DWORD PTR y[rip], edx ret negative: mov DWORD PTR g[rip], 0 ret
linkage.h
#ifndef LINKAGE_H_ #define LINKAGE_H_ int divide(int x, int y); #endif
关键修正说明
- 内存越界修复:将
QWORD PTR改为DWORD PTR,确保对g的写入仅操作4字节内存空间。 - 余数传递修复:直接将余数写入全局静态变量
y的内存地址,替代修改参数寄存器的无效操作。 - 位宽匹配:使用32位寄存器处理
int类型的参数与计算,符合C语言类型定义。 - 头文件修正:修正宏定义拼写错误,保证头文件功能正常。
内容的提问来源于stack exchange,提问作者komsire22
相关产品推荐
相关产品推荐

