我想添加以下数字:40、90、50 和 155,我得到的总数是 355。
我想试验和测试寄存器 AL 是否会有 (2^8) - 1 的位限制,当我编译代码并执行代码时,我得到了 1376331855 的小数。这是怎么发生的?
另外,我认为355大于255,结果应该显示溢出异常。
我知道如果我使用 MOVZX,我将能够将计算带入 AX 的高位寄存器。
此外,我对 AL 和 AH 之间的区别感到很困惑。 AL 和 AH 的内存分配有区别吗?
TITLE Adding
INCLUDE Irvine32.inc
.code
main PROC
mov al,0h ;
add al,28h ; 40
add al,5Ah ; 90
add al,32h ;50
add al,9Bh ;155
; total is 355
call DumpRegs
call writedec
exit
main ENDP
END main
最佳答案
Also, I am very confused with the difference between AL and AH. Is there a different in memory allocation for AL and AH?
不,不涉及内存。它们都是 EAX 中的字节寄存器。
- AX为EAX的低16位
- AH 和 AL 是 AX 的高低两部分
另见 this ascii-art diagram .或者在 C 中:
union eax {
uint32_t EAX; // regs aren't really signed or unsigned, but they have well-defined wraparound semantics like C unsigned (and unlike C signed).
uint16_t AX;
struct { uint8_t AL, AH; }; // anonymous struct, in little-endian order (AL is the low byte).
};
对任何成员的写入都会反射(reflect)在其他成员的值中,但不要将寄存器的其余部分清零。 (脚注 1)
你的 print 函数打印了所有的 EAX,但是你从来没有在打印它之前将 EAX 的高字节清零。 在进入 main
时,您需要假设 EAX 的所有字节都是随机垃圾。
main PROC
xor eax, eax ; zero eax
; mov al,0h ; instead of just zeroing al and leaving garbage in the upper 24 bits
add al,28h ; then play around with the low byte if you want
...
add al,9Bh ; AL wraps around, but no carry happens into the rest of EAX.
; If you want that, use a wider register:
; add eax, 9Bh
call writedec ; prints eax as a signed integer
I thought 355 is greater than 255, and as a result should display an overflow exception.
整数溢出设置标志,您可以稍后测试。 参见Understanding Carry vs. Overflow conditions/flags
它不会触发故障/异常。 (除了除法)
(1):严格的 ISO C90 和 ISO C++ 实际上不允许读取不是最后一个写入的联合成员(未定义行为)。 ISO C99, (and GNU C++ as an extension) do guarantee type-punning with unions works as expected .
关于算术中的汇编位内存限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39891735/