【问题标题】:assembly x86 test si组装 x86 测试系统
【发布时间】:2016-01-17 13:14:29
【问题描述】:
下面的代码是什么意思?
mov si, [L10003248]
test si, si
jnz L10004356
我认为这意味着如果L10003248 地址不为空,则跳转到L10004356。我认为它与存储在L10003248 中的值无关,否则它使用了word ptr。
我的假设正确吗?
这听起来不合逻辑。因为这个跳转看起来微不足道。
我没有关于编译器的信息。
【问题讨论】:
标签:
assembly
x86
reverse-engineering
【解决方案1】:
mov si, [L10003248]
确实与内存位置at L10003248有关,而不仅仅是地址。这由方括号唯一表示。
[...] 否则它使用了单词 ptr [...]
不,word ptr 不表示内存位置,而是表示内存位置的大小。
听从指令
mov [eax], 12h
现在,汇编器可以猜出12h 的大小。是 16 位 (0012h) 吗?还是 8 位 (12h)?这需要作为信息传递给汇编程序。在这里,ptr 指令开始发挥作用:
mov word ptr [eax], 12h
现在,汇编器明确知道必须复制 16 位数据。同样,可以添加 byte ptr 和 dword ptr。有关ptr 指令的更多信息,请阅读this。
另一种情况可以
mov [16_bit_mem], 12h
一些汇编器(比如 MASM)会记住变量的大小,所以这条指令编译得很好。 OTOH,有些(如 NASM 和 GNU)没有。在NASM中,你需要写
mov word ptr [16_bit_mem], 12h
向汇编器提供数据的大小。 GNU as 默认使用 AT&T 语法(与 MASM 和 NASM 使用的 Intel 语法相反)。在这里,您将后缀(b 用于byte、w、word、l 用于long 和q 用于quadword)到助记符而不是@98765434@指令:
movw 0x12, (16_bit_mem)
这当然是 AT&T 语法(源和目标操作数,交换,0x 而不是 h 等)。
【解决方案2】:
[L10003248]的意思是*L10003248,它是存储在地址L10003248中的值。
所以你的代码实际上意味着:
si = *L10003248;
if (si != 0)
jmp L10004356