算术中的汇编位内存限制

标签 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

.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/

相关文章:

assembly - 在除以零的中断处理程序中该怎么做?

assembly - 如何保护 x86 程序集中的多重声明?

c - 68HC11 上使用 4 字节数字的斐波那契数列

multithreading - 使用原子交换实现原子增量?

assembly - sub eax,0-它有作用吗?

c - 获取指令指针指向的给定地址的指令

x86 - 如何知道一个中断是硬件中断还是cpu异常

performance - 为左打包字节元素生成高效的 sse 洗牌掩码

eclipse - 什么是编写 NASM 的好 IDE?

assembly - NASM 是否不一致,或者我只是错过了 CMP 的一个明显事实?