Mac M1平台下C语言使用扩展汇编遇到的异常问题
Apple M1平台GCC扩展汇编未赋值输出却获取输入值的原因
这是GCC扩展汇编的未定义行为导致的,核心逻辑如下:
编译器的默认假设
GCC扩展汇编中,只要你声明了输出操作数(比如这里的"=r" (b)),编译器就默认你会在汇编代码里给对应的寄存器赋值。不管你实际有没有操作这个寄存器,编译器最终都会把该寄存器里的内容存回变量b。寄存器复用的优化
为了提升代码效率,GCC会尽可能复用寄存器。你的代码里,输入操作数a和输出操作数b都用了r约束(通用寄存器),编译器很可能直接把它们分配到同一个寄存器里——比如把a的值放到x0,同时让b的输出寄存器也是x0。你的汇编语句mov x1, x1是空操作,完全没碰这个寄存器,所以最终存回b的就是a原来的值。验证与调整方式
- 若给输出寄存器明确赋值,比如把汇编改成:
运行后"mov %0, #0" : "=r" (b) : "r" (a));b会被设为0,符合预期。 - 若想避免寄存器复用,给输出约束加上
&(早期clobber标记),改成"=&r" (b)。这时候编译器会给输入和输出分配不同的寄存器,再运行你的空操作汇编,b会变成随机垃圾值——这才是未赋值输出的真实未定义行为表现。
内容的提问来源于stack exchange,提问作者Krapo
相关产品推荐
相关产品推荐

