簡體   English   中英

如何在匯編中執行 aaa 指令到大於 99 的數字

[英]how to do aaa instruction in assembly to number bigger than 99

我為 X86 平台進行組裝工作,但我在為大於 99 的數字做 bcd 時遇到了問題。

我得到了 'AX' 123(十進制)並添加到它 5(十進制)然后我做了 'aaa' 但結果不是 128 而是 0106。我看到了算法並理解了為什么但我如何做 'aaa'編號超過 99
那是我的代碼:

mov ax,123
add ax,5
aaa

我試圖將“AX”除以 0ah 以分隔數字並使用“aad”,但我看到它禁止超過 99 的數字。

“AAA”指令(“ASCII Adjust After Addition”)只關心AL的最低 4 位中的值(字面意思是“ if(AL & 0x0F > 9) AX += (1 << 8) + (1 << 4) - 10; ", 或 "如果之前的加法導致最低半字節/數字溢出;然后從最低半字節/數字中減去 10,並將第二個半字節/數字加 1 以修復應該發生的進位但沒有,然后將 1 加上從第二個半字節/數字到第三個半字節/數字的進位,而大多數人希望這不會發生”)。

對於 8 位壓縮 BCD 加法(例如 AL 的最低半字節中的一個數字和 AL 的最高半字節中的另一個數字),這是頸部的主要痛苦 - 您必須將第一個半字節存儲在某處然后移動 AL 中的值向右並做第二個aaa來修復第二個半字節。 這可以通過旋轉來完成 - 例如aaa然后ror ax,4然后aaa然后rol ax,4

對於 8 位未壓縮 BCD 加法(例如 AL 的最低半字節中的一個數字和 AH 的最低半字節中的另一個數字),頸部的主要疼痛幾乎相同。

對於“12 位或更大”的壓縮 BCD 加法,它會變得越來越糟,因為第一個aaa會導致第三個半字節/數字可能被破壞(如果第一個半字節溢出,則增加 1 太多),第二個aaa可能會破壞第四個半字節/數字等

對於“12 位或更大”的未打包 BCD 加法,它會變得越來越糟,因為(對於 16 位代碼)現在您的數字必須分布在多個寄存器中,並且您最終將值混入/輸出 AL 只是為了使用aaa指令。

唯一明智的解決方案是永遠不要使用aaa ,除非您正在執行 4 位加法(這就是它在 64 位代碼中被刪除的原因 - 反正沒人使用它)。

最好的選擇是乍一看從 BCD 轉換為普通 integer,然后使用普通整數進行所有計算,然后在最后可能的機會從普通 integer 轉換回 BCD。 如果您可以使用 FPU,這種方法會特別好 - 例如fbld將 18 位(72 位)壓縮 BCD 值加載到 FPU 寄存器中,同時將其轉換為普通浮點值, fbstp將其轉換為普通浮點值成 BCD 並存儲。

反正...

    mov ax,123        ;This is not valid BCD - it's the value 0x7B or "7(11)" in decimal
    add ax,5          ;ax = 0x7B + 0x05 = 0x80
    aaa               ;This instruction does nothing because the lowest nibble is less than 9
                      ;Result = 0x80 or "80" in decimal

如果添加的原始值是有效的 BCD,那么您可能會得到如下信息:

    mov ax,121        ;ax = 0x79 or "79" in decimal
    add ax,5          ;ax = 0x79 + 0x05 = 0x7E
    aaa               ;0xE is is larger than 9, so "fix" it by adding 0x0106
                      ;ax = 0x0184
                      ;Result in AL = 0x84 or "84" in decimal

但是,這是一個“幸運的情況”,因為結果適合 2 位數。 它可能更像是:

    mov ax,152        ;ax = 0x98 or "98" in decimal
    add ax,5          ;ax = 0x99 + 0x05 = 0x9D
    aaa               ;0xD is is larger than 9, so "fix" it by adding 0x0106
                      ;ax = 0x01A3
                      ;Result in AX is a horribly broken mess (second digit not valid BCD, third digit correct)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM