C程序调用MASM汇编编写的光标定位函数参数传递错误问题求助
16位C与汇编混编参数传递异常问题解决
问题场景
开发环境为OpenWatcom + MASM 6.11,开发16位DOS程序时,C语言调用自定义汇编实现的光标设置函数,参数无法正确传递,汇编函数读取到的是无关的垃圾值。
原始问题代码
汇编实现代码
; Im failing super hard at writing this ; Function. .MODEL c, small .DATA? .DATA curpos_ PROTO C columns_:BYTE, rows_:BYTE .CODE public curpos_ curpos_ PROC C columns_:BYTE, rows_:BYTE mov dh, columns_ mov dl, rows_ mov bh, 0 mov ah, 2 int 10h ret curpos_ ENDP END
C侧调用代码
#include<stdio.h> #include<conio.h> #include<math.h> void clrscr(void); extern char _columns, _rows; extern void _curpos(char _columns, char _rows); void arcradius() { float w; float h; float radi = w / 2.0; float value; clrscr(); // 省略中间逻辑 _curpos(20,40); getch(); arcradius(); }
核心错误原因
- 命名冲突:C代码中声明了全局变量
_columns、_rows,和汇编函数的参数名冲突,汇编寻址时优先读取了全局变量的数值,而非栈上传递的参数值,所以读到垃圾数据 - 寄存器未保护:BIOS中断
int 10h会修改部分寄存器的值,原汇编没有保存bx寄存器的原始值,会破坏C程序的运行上下文 - 调用约定与函数名不匹配:C调用约定下MASM会自动给符合C约定的函数添加前导下划线,原汇编导出的
curpos_和C声明的_curpos存在命名匹配问题,栈平衡逻辑也不一致
修复后代码
汇编实现代码
; Im failing super hard at writing this ; Function. .MODEL small .DATA? .DATA curpos PROTO C _columns:BYTE, _rows:BYTE .CODE public curpos curpos PROC C _columns:BYTE, _rows:BYTE push bx mov dh, BYTE PTR _columns mov dl, BYTE PTR _rows mov bh, 0 mov ah, 2 int 10h pop bx ret 4 curpos ENDP END
C侧函数声明
extern void __stdcall curpos(char columns, char rows);
修复说明
- 移除了冲突的全局变量声明,调整参数命名避免和全局符号冲突
- 进入汇编函数后先压栈保存
bx寄存器,中断调用完成后恢复,避免破坏上层C程序的上下文 - 统一调用约定为
__stdcall,手动指定栈平衡的返回指令ret 4,保证调用后栈指针正确回滚 - 显式用
BYTE PTR指明参数的位宽,避免汇编器默认寻址错误
内容的提问来源于stack exchange,提问作者MadDog386
相关产品推荐
相关产品推荐

