汇编aaa指令

转载于:https://blog.csdn.net/swordmanwk/article/details/42519275

aaa(ASCII adjust after addition)指令,是BCD指令集中的一个指令,用于在两个未打包的BCD值相加后,调整al和ah寄存器的内容。

BCD(Binary-coded decimal)数是指2进制编码的10进制数,占据一个字节的低4位,只有0-9是有效值。
AAA指令做两件事情:
如果al的低4位是在0到9之间,保留低4位,清除高4位,如果al的低4位在10到15之间,则通过加6,来使得低4位在0到9之间,然后再对高4位清零。
如果al的低4位是在0到9之间,ah值不变,CF和AF标志清零,否则,ah=ah+1,并设置CF和AF标志。
下面看一个示例程序:

[plain] view plain copy
  1. section .data  
  2.   
  3.     EditBuff: db 'abcdefghijklm',10  
  4.     BUFFERLEN equ $-EditBuff  
  5.     FILLCHR   equ 35 ;'#'  
  6.       
  7. section .text  
  8.   
  9. WriteStr:  
  10.     push eax        ; Save pertinent registers  
  11.     push ebx  
  12.     mov eax,4       ; Specify sys_write call  
  13.     mov ebx,1       ; Specify File Descriptor 1: Stdout  
  14.     int 80H         ; Make the kernel call  
  15.     pop ebx         ; Restore pertinent registers  
  16.     pop eax  
  17.     ret         ; Go home  
  18.       
  19.     global  _start  
  20. _start:  
  21.     nop  
  22.       
  23.     mov ecx,EditBuff          
  24.     mov edx,BUFFERLEN     
  25.     call WriteStr  
  26.       
  27.     mov edi,EditBuff  
  28.     mov ecx,BUFFERLEN-1  
  29.     mov al,'1'  ; Start ruler with digit '1'  
  30. DoChar: stosb   ; Note that there's no REP prefix!  
  31.     add al,'1'  ; Bump the character value in AL up by 1  
  32.     aaa         ; Adjust AX to make this a BCD addition  
  33.     add al,'0'  ; Make sure we have binary 3 in AL's high nybble  
  34.     loop DoChar ; Go back & do another char until ECX goes to 0  
  35.                   
  36.     mov ecx,EditBuff          
  37.     mov edx,BUFFERLEN     
  38.     call WriteStr  
  39.   
  40. Exit:   mov eax,1       ; Code for Exit Syscall  
  41.     mov ebx,0       ; Return a code of zero   
  42.     int 80H         ; Make kernel call  

程序分析:
    mov edi,EditBuff //edi = EditBuff
    mov ecx,BUFFERLEN-1 //ecx= BUFFERLEN-1,这样可以不覆盖最后一个换行符
    mov al,'1' //al = ‘1’,1的ASCII码值是0x31,低4位恰好是有效的BCD值
DoChar: stosb //edi=al
    add al,'1' //两个ASCII码值相加。
    aaa  //使用aaa指令进行调整,使得低4位是有效的BCD值。只有’9’加’1’会形成无效BCD数(10),调整后al会等于0,其他都不需要调整低4位,只是简单对高4位清零。
    add al,'0' //要把数字转换成ASCII码,需要再把’0’加回来,例如9+’0’=’9’。
    loop DoChar //ecx=ecx-1,如果ecx不等于0,跳转到DoChar继续循环。ecx=13,所以会填充字符13次。

makefile文件内容:

[plain] view plain copy
  1. aaademo: aaademo.o  
  2.     ld -o aaademo aaademo.o  
  3. aaademo.o: aaademo.asm  
  4.     nasm -f elf -g -F stabs aaademo.asm -l aaademo.lst  

测试:

[plain] view plain copy
  1. [root@bogon aaademo]# make  
  2. nasm -f elf -g -F stabs aaademo.asm -l aaademo.lst  
  3. ld -o aaademo aaademo.o  
  4. [root@bogon aaademo]# ./aaademo   
  5. abcdefghijklm  
  6. 1234567890123  


猜你喜欢

转载自blog.csdn.net/liudongdong19/article/details/80551132
aaa
今日推荐