如何在GCC内联汇编中不通过寄存器直接跳转至目标地址?
无寄存器开销的跳转实现(GCC内联汇编)
可行实现方案
直接引用符号跳转
如果_start是全局可见的符号,直接在汇编模板里写符号名即可,GCC会自动生成相对或绝对跳转指令,完全不需要寄存器中转:__asm__("jmp _start");强制立即数输出
要是需要通过C层面的符号地址生成跳转,用%c0格式说明符配合i约束(编译期立即数约束),让GCC直接把符号地址作为立即数嵌入jmp指令:__asm__("jmp %c0" :: "i"(&_start));这里
%c0会告诉编译器不要把地址放进寄存器,而是直接输出成立即数形式。注意这个方法要求&_start是编译期可确定的常量地址。
关于"m"约束报错的原因
用"m"约束时,GCC会把操作数当成内存地址,但jmp指令的内存操作数是间接跳转格式(比如jmp *0x1011),不是你想要的直接跳转到0x1011的绝对跳转,所以会报错"memory input 0 is not directly addressable",这个约束本身就不符合你的需求场景。
需求可行性
完全可以通过GCC内联汇编实现无寄存器开销的跳转,选对约束和格式说明符,或者直接引用符号就能达到目的。
内容的提问来源于stack exchange,提问作者Raffaello
相关产品推荐
相关产品推荐

