算术中的汇编位内存限制
Assembly bit memory limit in arithmetic
我想添加以下数字: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 的高低两部分
另见 。或者在 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).
};
对任何成员的写入都会反映在其他成员的值中,但不要将寄存器的其余部分清零。 (脚注 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.
据我了解,DumpRegs 为您提供了 EAX 的输出。当我将您的答案转换为 HEX 时,我得到 5209284F,4F 在 AL 中。 4F HEX 是 79 Decimal,也就是 335 - 256。AL 寄存器只有 8 位,所以 256 是它能容纳的最大无符号整数。
在开始之前清除 EAX,结果可能更有意义。
我想添加以下数字: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 的高低两部分
另见
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).
};
对任何成员的写入都会反映在其他成员的值中,但不要将寄存器的其余部分清零。 (脚注 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.
据我了解,DumpRegs 为您提供了 EAX 的输出。当我将您的答案转换为 HEX 时,我得到 5209284F,4F 在 AL 中。 4F HEX 是 79 Decimal,也就是 335 - 256。AL 寄存器只有 8 位,所以 256 是它能容纳的最大无符号整数。
在开始之前清除 EAX,结果可能更有意义。