我知道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
当我汇编(和解散)时,得到以下结果:
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
),它被丢弃。
虽然我认为两者都是合理的输入输出,但我没有立即看到这种不一致处理的原因。这是否记录在某处?
似乎是intel语法模块中的错误。如果使用at&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 (;;)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句