我想添加以下数字: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
答案 0 :(得分:3)
另外,我对AL和AH之间的区别很困惑。 AL和AH的内存分配是否有所不同?
不,没有记忆。它们都是EAX中的字节寄存器。
另见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).
};
写入任何成员都会反映在其他成员的值中,但不会将其余部分归零。 (footnote1)
您的打印功能会打印所有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
我认为355大于255,因此应该显示溢出异常。
整数溢出设置标志,您可以稍后测试。 请参阅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
答案 1 :(得分:2)
据我了解,DumpRegs为您提供EAX的输出。当我将你的答案转换为HEX时,我得到5209284F,4F在AL中。 4F HEX为79十进制,为335 - 256.AL寄存器仅保存8位,因此256是它可以容纳的最大无符号整数。
在开始之前清除EAX,结果可能更有意义。