要求:输出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
程序现象