问题是我不能强迫gnu as
将jmp
解释为short
或near
,它总是将其解释为far
。
例如,以下代码会导致segfault
:
int main() {
asm volatile (
// ".intel_syntax noprefix\n\t"
// "jmp lbl%=\n\t"
// "lbl%=:\n\t"
"jmp *lbl%=(%%rip)\n\t"
"lbl%=:\n\t"
// ".att_syntax\n\t"
: : : );
return 0;
}
切换到注解的.intel_syntax
变体,它工作得非常好。
唯一的区别是intel
中的jmp lbl%=
变为eb 00
当att
中的jmp *lbl%=(%%rip)
变为ff 25 00 00 00 00
如果是.att_syntax
,如何强制将其解释为short jump
?
1条答案
按热度按时间23c0lvtd1#
jmp *lbl
执行一个 * 间接 * 跳转--从lbl:
的内存加载地址并跳转到该地址。在这种情况下,它获取此函数(函数epilog)之后的8个(代码)字节,并将其视为要跳转到的地址,从而导致segfault。对于一个简单的PC相对跳转,你只需要
jmp lbl
-- att语法和intel语法一样,不需要%rip
,因为所有的直接跳转都是相对于PC的。