x86汇编_ASCII和非压缩BCD码运算_AAA / AAS_笔记56

虽然 CPU 用二进制运算,但是也可以执行 ASCII 十进制串的运算。使用后者进行运算,对用户而言既便于输入也便于在控制台窗口显示,因为不用进行二进制转换。尽管 ASCII 运算执行速度比二进制运算要慢很多,但是它有两个明显的优点:1) 不必在执行运算之前转换串格式。2) 使用假设的十进制小数点,使得实数操作不会出现浮点运算的舍入误差的危险。有四类指令用于处理 ASCII 加法、减法、乘法和除法:AAA / AAS / AAM / AAD

AAA:ASCII adjust after addition。

执行加法后进行 ASCII 调整。将AX寄存器的内容转换为BCD码,但是这个内容是有条件的,必须先将AH设置0,然后AL的内容是由两个ASCII码的数字相加后的结果。如果AL存放其它不符合要求的内容,AAA指令的结果将没有意义。AAA指令的算法用C语言表达如下:

if ((and al, 0Fh) > 9 || AC == 1){
    if (8088 || 8086){
            al = al + 6
    else 
            ax = ax + 6
    }
    ah = ah + 1
    AC = 1 
    CY = 1
else
    AC = 0
    CY = 0
}
al = (and al, 0Fh)

下例展示了如何用 AAA 指令正确地实现 ASCII 数字 8 加 2。在执行加法之前,必须把 AH 清零,否则它将影响 AAA 执行的结果。最后一条指令将 AH 和 AL 转换为 ASCII 数字:

mov ah, 0
mov al, '8'                     ; AX = 0038h
add al, '2'                     ; AX = 006Ah
aaa                             ; AX = 0100h (结果进行 ASCII 调整)
or ax, 3030h                    ; AX = 3130h ='10' (转换为 ASCH 码)

使用AAA指令处理很长的ASCII码阿拉伯数字相加的例子,100123456789765 + 900402076502015。这里的难点是,虽然AAA指令能轻松地将两个ASCII的数字相加,但相加的结果可能会进位,下一位的数字相加时不要忘记把前面的进位一起算进去。

.386
.model flat, stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
INCLUDE Irvine32.inc

.data
decimal_one BYTE "100123456789765" 
decimal_two BYTE "900402076502015"
sum byte 15 dup(0), 0

.code
main PROC
    nop
    mov esi, offset decimal_one + 14
    mov edi, offset decimal_two + 14
    mov ebp, offset sum + 15
    mov ecx, 15
    mov bh, 0
    L1:
        mov ah, 0
        mov al, [esi]
        add al, [edi]
        AAA
        add al, bh
        AAA
        or ax, 3030h
        mov [ebp], al
        mov bh, ah
        dec ebp
        dec esi
        dec edi
    loop L1
    mov [ebp], bh
    nop
    invoke ExitProcess,0
main ENDP

end main

AAS (ASCII adjust after subtraction)

32 位模式下,AAS(做完减法后调整为ASCII码)指令紧随 SUB 或 SBB 指令之后,这两条指令执行两个非压缩BCD码的减法,并将结果保存到 AL 中。AAS 指令将 AL 转换为 ASCII 码的数字形式。

.386
.model flat, stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
INCLUDE Irvine32.inc

.data

.code
main PROC
    nop
    mov eax, 0
    mov al, '8'
    mov bl, '5'
    sub al, bl
    AAS
    invoke ExitProcess,0
main ENDP

end main

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值