旧版XV6的insl/outsl函数在2021.9版XV6编译报匹配约束不允许寄存器错误
XV6移植编译错误“Matching constraint does not allow a register”原因解析
错误核心原因
这个错误由两个层面的不匹配导致:
- 编译架构与代码架构不匹配:你所用的旧版
outsl/insl是32位x86架构的汇编实现,绑定的是32位寄存器esi、edi、ecx。2021版XV6默认使用的GCC 10+版本工具链对汇编约束的检查远严格于旧版工具链,如果编译时没有添加-m32参数生成32位代码,64位模式下寄存器为64位的rsi/rdi/rcx,和参数类型不匹配,触发约束校验失败。 - 汇编约束写法不符合高版本GCC规则:你原有代码把
addr、cnt设为输出操作数,本意是告知编译器这两个值对应的寄存器会被汇编指令修改,但这两个参数是函数形参(局部变量),修改后的值不会被外部使用,高版本GCC会判定该输出绑定无效,结合匹配约束0、1的校验,直接抛出匹配失败错误。
修复方案
调整汇编约束写法,不需要把寄存器修改值回写到变量,直接在破坏声明中标注被修改的寄存器即可,修改后代码如下:
static inline void outsl(int port, const void* addr, int cnt) { asm volatile("cld; rep outsl" : : "d"(port), "S"(addr), "c"(cnt) : "cc", "memory", "esi", "ecx"); } static inline void insl(int port, void* addr, int cnt) { asm volatile("cld; rep insl" : : "d"(port), "D"(addr), "c"(cnt) : "cc", "memory", "edi", "ecx"); }
同时确认Makefile中的编译参数添加了-m32,指定生成32位x86架构代码,即可解决编译错误。
内容的提问来源于stack exchange,提问作者Illuminati
相关产品推荐
相关产品推荐

