请问您能解释以下汇编程序代码的工作原理吗?
xor ebx, ebx;
mov bl, byte ptr[ecx];
cmp ebx, 0;
我不明白为什么你将字节移到bl
,之后你比较ebx
而不是bl
。
答案 0 :(得分:3)
ng
是bl
寄存器中低8位(位7-0)的名称。还有ebx
是bh
的15-8位,ebx
是低16位(位15-0)。高16位没有名称。
这适用于所有注册bx
,eax
,ebx
和ecx
。
鉴于edx
是第一个零&#d; dd,结果代码可能是编译器编译类似的东西的基本原因:
ebx
[或者可能只是char ch;
const char str;
int i;
...
ch = str[i];
if (ch == 0) ...
]。
32位的扩展将由"节省空间"或者"运行速度更快"或if (ch)
右侧有if (ch == 0)
的事实,需要将值比较为int
而不是{{} 1}} = byte - 我不能在没有看到原始源代码的情况下说出哪些内容 - 即使这样,编译器中的实际代码生成也是一系列复杂的决策,基于两者"什么运行得快哪个处理器"和"正确性根据语言"。
答案 1 :(得分:2)
该指令对EBX的所有32位和EBX的所有32位进行异或,将结果保留为EBX。您可以很容易地证明这与将0的值移动到EBX中相同(但它比执行此操作更快,因为这样就不需要内存提取)
xor ebx, ebx;
该指令将ECX指向的地址处的BYTE(8位)移入EBX的低8位,其他24位保持不变(它们为零 - 记得吗?)
mov bl, byte ptr[ecx];
该指令将EBX中的整个32位值与0进行比较 - 在这种情况下,它在逻辑上与仅将BL中的字节与0进行比较相同,因为我们知道高24位将为0
cmp ebx, 0;
(预期)为什么这样做?
因为这是一个32位处理器。与8位值相比,它更适合在32位值上运行。编译器知道这一点,并且一旦允许,它将始终寻求将较小的值提升为较大的值。
答案 2 :(得分:0)
BL
是EBX
寄存器的低字节,因此您之前xor
EBX
EBX
之前,您需要将0与{0}进行比较{1}}低字节等于BL
。
答案 3 :(得分:0)
从纯粹的最终效果来看,
之间没有区别CMP ebx,0
和
CMP bl,0
在给定的情况下,因为在这组指令之前已经存在XOR EBX,EBX。第一个命令在符号扩展imm8值之后执行,因此在这种情况下,通过在临时寄存器中执行减法执行的有效比较总是32位。操作码长度也相同:80/7 / ib和83/7 / id。
然而,从数据总线流的角度来看,数据总线经过优化,可以更快地读取32位数据流,因为它不必执行带内部掩码的AND来隔离寄存器的8位数据内容,因此,汇编程序编写者建议使用最佳总线宽度 - 通常是32的倍数。因此,你会看到cmp ebx,0作为cmp bl,0的首选代码转换。
玩得开心......