汇编语言(王爽)——实验十 编写子程序

一、显示字符串

1、内容

2、个人代码

assume cs:code

data segment
db 'Welcome to masm!',0
data ends

code segment
start:mov dh,8;行号
mov dl,3;列号 屏幕的8行3列(从0开始)
mov cl,2;属性值(绿色)
mov ax,data
mov ds,ax;ds->data数据段
mov si,0;取字符串字符
call show_str

mov ax,4c00h
int 21h

show_str:
push cx
push si
push dx
mov di,0
add dl,dl;计算在显存中(字节)列号(从0开始)如显存第三个字符是第6个字节(从0起)

change:
mov al,cl;暂时存储cl颜色属性
mov cl,[di];取ds一个字节
mov ch,0
jcxz ok;判断是否为0,为0结束跳到标号ok,否则继续
mov cl,al;恢复cl颜色属性值
mov al,160;每行80个字符160个字节
mul dh;结果存在ax中,是第8行(初始行为1)之前的字节数
mov bl,16
div bl;除数在一个reg或内存单元中,结果存到al中
mov ah,0
add ax,0b800h;计算第8行的首地址
mov es,ax;es为第8行的首地址
mov al,[di];取字符串字符,di每次加1
mov bl,dl
mov bh,0;bx是列的偏移地址
mov byte ptr es:[si+bx],al;si每次加2,al每次取字符串的一个字符
mov es:[si+bx+1],cl;颜色属性值为cl
add si,2;在显存中每次写入两个字节	
inc di;字符串每次取一个字节
jmp short change

ok:
pop dx
pop si
pop cx
ret
code ends

end start

3、结果

 

二、解决除法溢出的问题

1、内容

2、个人代码

assume cs:code

code segment
start:
mov ax,4240h
mov dx,000fh;被除数32位
mov cx,0ah;除数16位
call divdw;调用子程序
mov ax,4c00h
int 21h

divdw:
push bx
push si
push di;保存主程序寄存器内容,子程序返回前恢复,dx、ax、cx是要返回的不用入栈保存
mov bx,ax;把被除数低16位存到bx
mov ax,dx;高16位存到ax
mov dx,0
div cx;计算原被除数的高16位除以原除数ax存商dx存余数
mov si,ax;商存到si
mov di,dx;余数存到di
mov dx,si
mov ax,0;乘以65536等于在低位加上16个0
push dx
push ax;高位和低位分别入栈
mov dx,di
mov ax,0
add ax,bx
div cx;商存到ax,余数dx
pop di;低位
pop si
add di,ax;计算商,低16位不会进位
mov ax,di;商低16位存到ax
mov cx,dx;余数存到cx
mov dx,si;商高16位存到dx
pop di
pop si
pop bx
ret
code ends

end start

3、结果

 

子程序有的需要栈保存主程序寄存器内容,子程序返回前恢复;而有返回数据的有些寄存器不需要入栈,需要这些寄存器接受返回数据

 

三、数值显示

1、内容

2、个人代码

assume cs:code

data segment
db 10 dup (0);10个字节
data ends

code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
call dtoc
mov dh,8
mov dl,3
mov cl,2
call show_str

mov ax,4c00h
int 21h

dtoc:
push ax
push bx
push cx
push dx
;在data段中写入数据'12666'
mov bx,0
push bx;0入栈标识数据结尾
mov cx,10
mov dx,0

s0:
call divdw;调用divdw子程序,求每位的值cx余数dx、ax商
;调用前面写的解决除法溢出的子程序,这里也可以用16位除32位计算但不能用8位除16位(商溢出)
add cx,30h
push cx;得到ascii,入栈
mov cx,ax
jcxz s1;商为0跳到s1
mov cx,10;除数为10
jmp s0

s1:
pop ax
mov cx,ax
jcxz s2;栈顶数据为0,数据结束
mov [bx],al
inc bx
jmp s1

s2:
mov [bx],al;得到字符串后以数0结尾
pop dx
pop cx
pop bx
pop ax
ret

show_str:
push cx
push si
push dx
mov di,0
add dl,dl;计算在显存中(字节)列号(从0开始)如显存第三个字符是第6个字节(从0起)

change:
mov al,cl;暂时存储cl颜色属性
mov cl,[di];取ds一个字节
mov ch,0
jcxz ok;判断是否为0,为0结束跳到标号ok,否则继续
mov cl,al;恢复cl颜色属性值
mov al,160;每行80个字符160个字节
mul dh;结果存在ax中,是第8行(初始行为1)之前的字节数
mov bl,16
div bl;除数在一个reg或内存单元中,结果存到al中
mov ah,0
add ax,0b800h;计算第8行的首地址
mov es,ax;es为第8行的首地址
mov al,[di];取字符串字符,di每次加1
mov bl,dl
mov bh,0;bx是列的偏移地址
mov byte ptr es:[si+bx],al;si每次加2,al每次取字符串的一个字符
mov es:[si+bx+1],cl;颜色属性值为cl
add si,2;在显存中每次写入两个字节	
inc di;字符串每次取一个字节
jmp short change

ok:
pop dx
pop si
pop cx
ret

divdw:
push bx
push si
push di
mov bx,ax;把被除数低16位存到bx
mov ax,dx;高16位存到ax
mov dx,0
div cx;计算原被除数的高16位除以原除数ax存商dx存余数
mov si,ax;商存到si
mov di,dx;余数存到di
mov dx,si
mov ax,0;乘以65536等于在低位加上16个0
push dx
push ax;高位和低位分别入栈
mov dx,di
mov ax,0
add ax,bx
div cx;商存到ax,余数dx
pop di;低位
pop si
add di,ax;计算商,低16位不会进位
mov ax,di;商低16位存到ax
mov cx,dx;余数存到cx
mov dx,si;商高16位存到dx
pop di
pop si
pop bx
ret

code ends
end start

3、结果

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

z2bns

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值