mov bl在装配中做什么
What does mov bl do in assembly
你能解释一下下面的汇编代码是如何工作的吗?
xor ebx, ebx;
mov bl, byte ptr[ecx];
cmp ebx, 0;
我不明白为什么把字节移到bl
,然后比较ebx
而不是bl
。
bl
是ebx
寄存器中低8位(位7-0)的名称。还有作为ebx
的比特15-8的bh
,并且bx
是低16比特(比特15-0)。较高的16位没有名称。
这适用于所有寄存器eax
、ebx
、ecx
和edx
。
假设ebx
首先为零,则生成的代码可能是编译器编译以下内容的结果:
char ch;
const char str;
int i;
...
ch = str[i];
if (ch == 0) ...
[或者可能只是if (ch)
]。
扩展到32位可能是由于"节省空间"或"运行速度更快",或者if (ch == 0)
右侧有一个int
,需要将值比较为int
,而不是char
=字节-如果没有看到原始源代码,我无法说出是哪一个-即使这样,编译器中的实际代码生成也是一组相当复杂的决策,基于"什么在哪个处理器上运行得快"answers"根据语言的正确性"。
此指令在EBX的所有32位和EBX的全部32位之间形成异或,将结果留在EBX中。你可以很容易地证明这与将0的值移动到EBX中是一样的(但它比这样做更快,因为这样就不需要内存提取)
xor ebx, ebx;
此指令将ECX指向的地址处的BYTE(8位)移动到EBX的LOW 8位,使其他24位保持不变(它们是零-还记得吗?)
mov bl, byte ptr[ecx];
此指令将EBX中的整个32位值与0进行比较-在这种情况下,它在逻辑上与将BL中的字节与0进行对比相同,因为我们知道高24位将为0
cmp ebx, 0;
(预期)为什么会这样?
因为这是一个32位处理器。它适合于对32位值进行操作,比对8位值进行更有效的操作。编译器知道这一点,并且在允许的情况下,总是试图将较小的值提升为较大的值。
BL
是EBX
寄存器的低字节,因此,由于您之前是xor
和EBX
,因此您将0与EBX
进行比较,其低字节等于BL
。
从纯末端效应的角度来看,之间没有区别
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的首选代码转换。
有乐趣的编程。。。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 我应该使用什么来代替void作为变体中的替代类型之一
- mov bl在装配中做什么