汇编程序题集
分支程序设计
题一
Q:编写程序实现函数$y=\begin{cases} & -1\text{ , } x< 0 \\ & 0\text{ , } x=0 \\ & 1\text{ , } x>0 \end{cases}$。
流程图如下:
代码如下:
data segment;数据段定义 x db 1 y db 0 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov al,x cmp al,0 jge next1;大于等于跳转 mov al,-1 jmp done next1: je done;等于跳转 next2: mov al,1 done: mov y,al code ends end start
循环程序设计
题一
Q:编程统计BUFF为首地址的缓冲区中负数的个数。
流程图如下:
代码如下:
data segment;数据段定义 buff db -8,2,4,-5,-7 len dw 5 cnt db 0 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov dl,0 lea bx,buff;获取缓冲区首地址 mov cx,len;获取缓冲区长度 next1: mov al,[bx];取一个数据到AL add al,0;使数据影响标志位 jns next2;不为负数跳转 inc dl;计数+1 next2: inc bx;地址加1 loop next1 mov cnt,dl code ends end start
题二
Q:在BUFF存储区有一个字符串,试统计“%”之前的字符个数。
流程图如下:
代码如下:
data segment;数据段定义 buff db 'abcde%fgh';字符串定义 len equ $-block;符号定义 cnt db 0 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax lea si,buff;获取缓冲区首地址 mov cx,len;获取缓冲区长度 loop1: mov al,[si];取一个数据到AL cmp al,'%';判断字符是否为% je done;相等跳转 inc cnt;计数+1 inc si;地址+1 loop loop1 done: code ends end start
题三
Q:将BUFFS的前N个字符逆序传递到BUFFD中。
T:使用SI和DI寄存器分别控制BUFFS和BUFFD的地址。
流程图:
代码如下:
n equ 5 data segment buffs dw 'hello world!$' buffd dw 20 dup('$') data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax lea si,buffs add si,n dec si lea di,buffd mov cx,n loop1: mov al,[si] mov [di],al dec si inc di loop loop1 code ends end start
子程序设计
题一
Q:编写一个子程序,计算(AX+BX)*AX,结果的高16位保存在DX中,低16位保存在AX中,并在主程序中进行调用。
T:子程序入口为AX,BX;出口是AX,DX;所以必须在子程序中对BX进行保护。
代码如下:
code segment main proc;主程序 start: mov ax,0004H mov bx,0005H call proc1;子程序调用 call proc1;子程序调用 int 00H;程序中断 main endp proc1 proc near;子程序定义 push bx;保护BX pushf;//保护标志寄存器 add bx,ax mul bx popf;//恢复标志寄存器 pop bx;恢复BX ret proc1 endp code ends end start
程序调试与交互
题一
Q:键盘输入两个一位十进制数,求和以后通过屏幕进行打印输出。例如,输入7和8,则输出15。
T:键盘的输入和屏幕输出都是ASCII码,转换关系是ASCII=十进制数+30H,而十进制数就是ASCII码的低四位;两个一位十进制数相加,属于BCD码运算,需要借助AAA加法调整指令对结果进行校正。
代码如下:
code segment assume cs:code,ds:data start: mov ah,1;调用号1,输入字符 int 21h;DOS系统功能调用 mov bl,al;获取输入的字符 int 21h add al,bl;获取字符并相加 mov ah,0;ah清零,用于BCD校正 aaa;分离BCD加法校正 mov bl,al;存储个位字符 mov dl,ah;十位字符送进入口 add dl,30h;转ASIC mov ah,2;调用号2,显示字符 int 21h mov dl,bl;个位字符送进入口 add dl,30h;转ASIC int 21h code ends end start
题二
Q:键盘输入一串字符,程序打印输出相同的字符内容。
T:字符串输入输出都以DX作为入口,指出缓冲区首地址;其中,字符串输入要求实现定义一个缓冲区,第一字节指明缓冲区长度,第二字节指明实际可输入的字符个数(包括自动添加的结尾符),其后区域作为字符串存储区;字符串输出要求以“$”作为结尾。
代码如下:
data segment buff1 db 10;缓冲区容纳量 db 10;实际可输入字符个数 buff2 db 10 dup('$');用于存放字符串输入 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax lea dx,buff1;将首地址送进入口 mov ah,10;调用号10,字符串输入 int 21h lea dx,buff2;将首地址送进入口 mov ah,9;调用号9,字符串输出 int 21h code ends end start