Assembly 算术中的汇编位内存限制
我想加上以下数字:40,90,50和155,我得到的总数是355 我想试验和测试寄存器AL是否有(2^8)-1的位限制,当我编译代码并执行代码时,我得到的十进制数是1376331855。那是怎么发生的 另外,我认为355大于255,因此应该显示溢出异常 我知道如果我使用MOVZX,我将能够将计算结果放入AX的较高寄存器 另外,我对AL和AH之间的区别感到非常困惑。AL和AH是否有不同的内存分配Assembly 算术中的汇编位内存限制,assembly,x86,nasm,masm,irvine32,Assembly,X86,Nasm,Masm,Irvine32,我想加上以下数字:40,90,50和155,我得到的总数是355 我想试验和测试寄存器AL是否有(2^8)-1的位限制,当我编译代码并执行代码时,我得到的十进制数是1376331855。那是怎么发生的 另外,我认为355大于255,因此应该显示溢出异常 我知道如果我使用MOVZX,我将能够将计算结果放入AX的较高寄存器 另外,我对AL和AH之间的区别感到非常困惑。AL和AH是否有不同的内存分配 TITLE Adding INCLUDE Irvine32.inc .c
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
另外,我对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
不,不涉及记忆。它们都是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)
打印函数打印所有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,因此应该显示溢出异常 整数溢出设置标志,您可以稍后进行测试请参见 它不会触发故障/异常。(除名除外)
(1):严格的ISO C90和ISO C++实际上不允许读取一个不是最后一个写的联合成员(未定义行为)。p> 另外,我对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
不,不涉及记忆。它们都是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)
打印函数打印所有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,因此应该显示溢出异常 整数溢出设置标志,您可以稍后进行测试请参见 它不会触发故障/异常。(除名除外)
(1):严格的ISO C90和ISO C++实际上不允许读取一个不是最后一个写的联合成员(未定义行为)。p> 据我所知,DumpRegs提供了EAX的输出。当我把你的答案转换成十六进制时,我得到了5209284F,在AL.4F十六进制中的4F是79位小数,也就是335-256位。AL寄存器只保存8位,因此256是它可以保存的最大无符号整数
在开始之前清除EAX,结果可能会更有意义。据我所知,DumpRegs为您提供了EAX的输出。当我把你的答案转换成十六进制时,我得到了5209284F,在AL.4F十六进制中的4F是79位小数,也就是335-256位。AL寄存器只保存8位,因此256是它可以保存的最大无符号整数
开始前清除EAX,结果可能更有意义。用
mov-ax,0h
或mov-EAX,0h
替换。我认为Irvine库使用EAX。我理解您为什么会这样做,但我对使用寄存器AL产生的值感到好奇。为什么是该值而不是溢出错误?谢谢。可能发生了溢出,但您没有检查它。因此,在命令行中,当溢出发生时,它不会告诉您,而是会产生一个模糊的数字?谢天谢地,塞姆利有着神秘的方式。您可以使用jxx指令(JO)检查溢出。将mov-al,0h
替换为mov-ax,0h
或mov-eax,0h
。我认为Irvine库使用EAX。我理解您为什么会这样做,但我对使用寄存器AL产生的值感到好奇。为什么是该值而不是溢出错误?谢谢。可能发生了溢出,但您没有检查它。因此,在命令行中,当溢出发生时,它不会告诉您,而是会产生一个模糊的数字?谢天谢地,塞姆利有着神秘的方式。您可以使用jxx指令(JO)检查溢出。是的,这正是我在回答中所期望和说的。但是+1用于向OP显示低位字节确实包含预期值。255是最大值。它可以容纳256个值,但由于0也是一个值,255是最高值。是的,这正是我在回答中所期望和说的。但是+1用于向OP显示低位字节确实包含预期值。255是最大值。它可以容纳256个值,但由于0也是一个值,因此255是最高值。