8086汇编-分两行打印26个字母

要求:输出ASCII表中的小写字母部分,要求每行13个字符。

loop指令实现

使用loop指令两次,分两行打印字母表。

首先,用C语言写出对应程序,如下

#include <stdio.h>
int main() {
    for (int i = 0; i < 26; i++) {
        printf("%c", 'A'+i);
        if (i == 12) printf("\n");
    }
    return 0;
}

gcc编译,生成.o文件

gcc -c loop.c

输入指令,执行反汇编

objdump -S loop.o

查看main函数反汇编结果

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 30             sub    $0x30,%rsp
   8:   e8 00 00 00 00          callq  d <main+0xd>
   d:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
  14:   83 7d fc 19             cmpl   $0x19,-0x4(%rbp)
  18:   7f 23                   jg     3d <main+0x3d>
  1a:   8b 45 fc                mov    -0x4(%rbp),%eax
  1d:   83 c0 41                add    $0x41,%eax
  20:   89 c1                   mov    %eax,%ecx
  22:   e8 00 00 00 00          callq  27 <main+0x27>
  27:   83 7d fc 0c             cmpl   $0xc,-0x4(%rbp)
  2b:   75 0a                   jne    37 <main+0x37>
  2d:   b9 0a 00 00 00          mov    $0xa,%ecx
  32:   e8 00 00 00 00          callq  37 <main+0x37>
  37:   83 45 fc 01             addl   $0x1,-0x4(%rbp)
  3b:   eb d7                   jmp    14 <main+0x14>
  3d:   b8 00 00 00 00          mov    $0x0,%eax
  42:   48 83 c4 30             add    $0x30,%rsp
  46:   5d                      pop    %rbp
  47:   c3                      retq

发现gcc把C语言代码翻译成汇编时使用了条件跳转。

考虑每行输出13个字母,所以cx寄存器设置13,为内圈循环次数。把外圈循环次数2放入bx低八位暂存

mov bl,2    ;外圈循环次数
mov cx,13   ;内圈循环次数

loop2主要负责打印完一行后输出回车

loop2:              ;外圈循环开始
        mov cx,13   ;第二次要重新初始化次数
loop1:              ;内圈循环开始
        ......
        loop loop1  ;内圈循环结束
​
        mov bh,dl   ;暂存当前字符
        mov dl,0ah  ;存入回车
        int 21h     ;打印回车
        mov dl,bh   ;恢复当前字符
        mov cl,bl   ;计数器更新外圈循环次数
        sub bl,1    ;外圈循环次数-1
​
        loop loop2  ;外圈循环结束

loop1负责打印一行字母

loop1:              ;内圈循环开始
        int 21h     ;打印字符
        add dl,1    ;ASCII+1
        loop loop1  ;内圈循环结束

完整代码

code segment
         assume cs:code
start:
        mov bl,2    ;外圈循环次数
        mov cx,13   ;内圈循环次数
        mov ah,02h
        mov dl,'a'  ;字符a
loop2:              ;外圈循环开始
        mov cx,13   ;第二次要重新初始化次数
loop1:              ;内圈循环开始
        int 21h     ;打印字符
        add dl,1    ;ASCII+1
        loop loop1  ;内圈循环结束
        mov bh,dl   ;暂存当前字符
        mov dl,0ah  ;存入回车
        int 21h     ;打印回车
        mov dl,bh   ;恢复当前字符
        mov cl,bl   ;计数器更新外圈循环次数
        sub bl,1    ;外圈循环次数-1
        loop loop2  ;外圈循环结束
        mov ah,4ch
        int 21h
code ends
       end start
用条件跳转指令实现

条件跳转当判断当前输出数量是13个字母时,打印回车,否则跳转继续输出字母。所以开始时,打印数量直接设置为26

mov cx,26

打印第一行

row1:               ;打印第一行
        sub cx,1    ;次数-1
        int 21h     ;打印字符
        add dl,1    ;ASCII+1
        cmp cx,13   ;比较
        jne row1    ;不等跳转

打印回车

mov bl,dl   ;暂存当前字符
mov dl,0ah  ;存入回车
int 21h     ;打印回车
mov dl,bl   ;恢复当前字符

打印第二行

row2:               ;打印第二行
        sub cx,1    ;次数-1
        int 21h     ;打印字符
        add dl,1    ;ASCII+1
        cmp cx,0    ;比较
        jne row2    ;不等跳转

完整代码

code segment
         assume cs:code
start:
        mov cx,26
        mov ah,02h
        mov dl,'a'  ;字符a
row1:               ;打印第一行
        sub cx,1    ;次数-1
        int 21h     ;打印字符
        add dl,1    ;ASCII+1
        cmp cx,13   ;比较
        jne row1    ;不等跳转
        mov bl,dl   ;暂存当前字符
        mov dl,0ah  ;存入回车
        int 21h     ;打印回车
        mov dl,bl   ;恢复当前字符
row2:               ;打印第二行
        sub cx,1    ;次数-1
        int 21h     ;打印字符
        add dl,1    ;ASCII+1
        cmp cx,0    ;比较
        jne row2    ;不等跳转
        mov ah,4ch
        int 21h
code ends
       end start

程序现象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值