王爽 汇编语言 第三版 实验10 编写子程序

    xiaoxiao2021-03-25  99

    1、显示字符串

    源代码

    assume cs:code data segment db 'Welcome to masm!',0 data ends code segment start: mov dh,8 mov dl,3 mov cl,2 mov ax,data mov ds,ax mov si,0 call show_str mov ax,4C00H int 21H ;--------------------------------------------------------- ;名称:show_str ;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串 ;参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79), ; (cl)=颜色,ds:si指向字符串的首地址 ;返回:无 ;--------------------------------------------------------- show_str: ;B800H显示缓冲区的起始地址,关于显示缓冲区的问题可以参考实验9 mov ax,0B800H mov es,ax ;计算对应行号的起始偏移地址,一行有0A0H个字节(行数 * 0A0H = 偏移地址) mov al,dh mov bl,0A0H mul byte ptr bl mov bp,ax ;计算对应列号的起始偏移地址,一列有2个字节(列号 * 2 = 偏移地址) mov ah,0 mov al,dl add ax,ax mov di,ax mov ah,cl ;设置对应的颜色值 ;----------------------------------------------------------------------------------------- ;名称:print ;功能:向屏幕输出字符 ;参数:(si)=偏移地址(字符串段地址 ds),(bp)=从哪一行的偏移地址开始,(显示缓冲区段地址 es) ; (di)=从哪一列的偏移地址开始,(显示缓冲区段地址 es) ;返回:无 ;----------------------------------------------------------------------------------------- print: ;取得ds段偏移地址为si的字节数据,并保存到 cl 中 mov ch,0 mov cl,ds:[si] jcxz ok ;如果cx的值为0,是则跳转到 ok 标号 mov al,ds:[si] ;将字节数据保存到 al 中 mov es:[bp+di],ax ;输出到指定的显示缓冲区位置上 ;累加操作 add di,2 inc si jmp short print ok: ret code ends end start

    程序运行示例图

    2、解决除法溢出的问题

    源代码

    assume cs:code code segment main: mov ax,4240H mov dx,000FH mov cx,0AH call divdw mov ax,4C00H int 21h ;------------------------------------------------------------------------------ ;名称:divdw ;功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型 ;参数:(ax)=dword型数据的低16位 ; (bx)=dword型数据的高16位 ; (cx)=除数 ;返回:(dx)=结果的高16位 ; (ax)=结果的低16位 ; (cx)=余数 ;------------------------------------------------------------------------------ divdw: push ax ;将低16位保存到栈中 ;根据公式:X/N = int(H/N)*65536+[rem(H/N)*65536+L]/N mov ax,dx ;设置ax为高16位 mov dx,0 call doDiv ;跳转到doDiv执行取得商int()和余数rem() mov bx,si ;此时的商int()为结果的高16位,先保存到bx寄存器中 pop ax ;从栈中取出低16位设置给ax mov dx,di ;dx为rem() call doDiv ;跳转到doDiv执行 mov dx,bx ;设置结果的高16位 mov ax,si ;设置结果的低16位 mov cx,di ;设置余数 ret ;--------------------------------------- ;名称:doDiv ;功能:两数相除 取商,取余数 ;参数:(ax)=底16位,(dx)=高16位,(cx)=除数 ;返回:(si)=商,(di)=余数 ;--------------------------------------- doDiv: div word ptr cx mov si,ax mov di,dx ret code ends end main

    程序运行示例图

    call divdw前

    call divdw后

    3、数值显示

    源代码

    assume cs:code data segment db 10 dup(0) data ends code segment start: mov ax,12666 mov bx,data mov ds,bx mov si,0 call dtoc mov dh,8 mov dl,3 mov cl,2 call show_str mov ax,4C00H int 21H ;--------------------------------------------------------------- ;名称:dtoc ;功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符 ;参数:(ax)=word型数据 ; di:si指向字符串的首地址 ;返回:无 ;--------------------------------------------------------------- dtoc: mov cx,ax ;如果cx为0,则表示除到最后了,跳转到ok1 jcxz filling ;循环取余数操作,列如ax=12666,依次拿12666,1266,126,12,1去除以10取得余数 mov dx,0 mov bx,10 div word ptr bx add dx,30H ;余数需进行+30H操作(十进制数码字符对应的ASCII码 = 十进制数码值 + 30H) push dx ;将数据放入栈中 inc si jmp short dtoc ;------------------------------------- ;名称:filling ;功能:向ds段地址(字符串)填充数据 ;参数:(si)=数据个数(向栈中取几次数据) ;返回:无 ;------------------------------------- filling: mov cx,si mov si,0 a: pop ax mov ds:[si],al inc si loop a mov ds:[si],cl ;保证字符串以0为结尾符 mov si,0 ;修改为0,保证show_str正确执行 ret ;以下代码从第一题复制而来 show_str: mov ax,0B800H mov es,ax mov al,dh mov bl,0A0H mul byte ptr bl mov bp,ax mov ah,0 mov al,dl add ax,ax mov di,ax mov ah,cl print: mov ch,0 mov cl,ds:[si] jcxz ok mov al,ds:[si] mov es:[bp+di],ax add di,2 inc si jmp short print ok: ret code ends end start

    程序运行示例图

    转载请注明原文地址: https://ju.6miu.com/read-22310.html

    最新回复(0)