32位编译下汇编约束'i'传入字符串地址作为立即数报错但-fno-pic编译正常的原因咨询
32位编译下汇编约束'i'传入字符串地址作为立即数报错但-fno-pic编译正常的原因咨询
嘿,这个问题我刚好碰到过类似的情况,给你捋明白其中的门道:
首先得搞懂你用的汇编约束'i'到底要求什么——它指定的是编译时就能确定的立即数,也就是那种固定不变、能直接塞进汇编指令里的常量值。
咱们来看你的代码:你给'i'约束传了两个参数,一个是数字45(这个没问题,本身就是立即数),另一个是字符串"ud2.c"的地址。这里的关键就在于32位GCC默认的编译模式是PIC(位置无关代码):
- 在PIC模式下,程序要能被加载到内存的任意地址运行,所以像字符串这种全局符号的地址不能被硬编码成固定值,而是要通过GOT(全局偏移表)来间接获取。这时候
"ud2.c"的地址根本不是一个编译时就能确定的立即数,不符合'i'约束的要求,编译器自然就报错了。
而当你加上-fno-pic参数时,编译模式就变成了位置相关代码:
- 这时候编译器会把全局符号(比如你的字符串
"ud2.c")的地址编译成固定的绝对地址,这个地址在编译阶段就能完全确定,完美符合'i'约束对立即数的要求,所以代码就能正常编译通过了。
另外你代码里用的%c0格式符,是告诉GCC把操作数当作立即数形式输出,这也进一步要求了对应的参数必须是能被当作立即数处理的值,这也是PIC模式下报错的一个触发点。
备注:内容来源于stack exchange,提问作者user14825657
相关产品推荐
相关产品推荐

