我知道MOD + R / M字段中的位移最大是一个带符号的32位整数。但是,当我传递一个对于32位有符号的值太大但对于无符号32位小的值时,我发现了一些不一致的行为。
案例:
.intel_syntax noprefix
mov [eax + eax + 0xdeadbeef], al
mov [r10d + r10d + 0xdeadbeef], al
mov [rax + rax + 0xdeadbeef], al
mov [r10 + r10 + 0xdeadbeef], al
当我收集(和dissasamble)时,我得到以下结果:
0: 67 88 84 00 ef be ad mov BYTE PTR [eax+eax*1-0x21524111],al
7: de
8: 67 43 88 84 12 ef be mov BYTE PTR [r10d+r10d*1-0x21524111],al
f: ad de
11: 88 04 00 mov BYTE PTR [rax+rax*1],al
14: 43 88 04 12 mov BYTE PTR [r10+r10*1],al
可以看出,对于32位寄存器(eax
,r10d
),32位位移按字面意思(并解释为带符号的32位整数)和64-位寄存器(rax
,r10
),它被丢弃。
虽然我认为两者都是输入的合理输出,但我没有立即看到这种不一致处理的原因。这是在某处记录的吗?
答案 0 :(得分:3)
似乎是intel语法模块中的一个错误。如果您使用& t语法:
,则会出现错误消息mov %al, 0xdeadbeef(%rax, %rax)
结果:
Error: 0xdeadbeef out range of signed 32bit displacement
更新:该错误似乎是因为baseindex
标志在i386_finalize_displacement
被调用后设置,只有在设置时才会检测到错误。一个简单的解决方法是移动之前设置的标志。我没有看到任何明显的问题,至少解决了这个问题:
--- tc-i386-intel.c.orig 2012-01-16 04:06:06.000000000 +0100
+++ tc-i386-intel.c 2014-06-14 16:13:31.238740524 +0200
@@ -835,6 +835,9 @@
memcpy (expP, &exp, sizeof(exp));
resolve_expression (expP);
+ if (intel_state.base || intel_state.index)
+ i.types[this_operand].bitfield.baseindex = 1;
+
if (expP->X_op != O_constant
|| expP->X_add_number
|| (!intel_state.base
@@ -882,9 +885,6 @@
return 0;
}
- if (intel_state.base || intel_state.index)
- i.types[this_operand].bitfield.baseindex = 1;
-
if (intel_state.seg)
{
for (;;)