《汇编语言》王爽著(第三版)实验十(个人方法记录)

可能有点乱,大家凑合看,错误不足请指正!

1、显示字符串

assume cs:code, ds:data, ss:stack

;数据段
data segment
    db 'Welcome to masm!',0
data ends

;栈段
stack segment
    dw 16 dup(0)
stack ends

;代码段
code segment

    start:
        mov ax,stack
        mov ss,ax
        mov sp,20H

        ;在第83列显示绿色字符串
        mov dh,8
        mov dl,3
        mov cl,2
        mov ax,data
        mov ds,ax
        mov si,0
        call show_str

        ;在第93列显示红色字符串
        mov dh,9
        mov dl,3
        mov cl,4
        mov ax,data
        mov ds,ax
        mov si,0
        call show_str

        mov ax,4c00H
        int 21H

    show_str:
        push dx
        push cx
        push si
        push di

        mov ax,0B800H
        mov es,ax

        ;计算行地址
        sub dh,1
        mov al,dh
        mov bl,0A0H
        mul bl
        mov di,ax

        ;加上列地址
        mov al,2
        mul dl
        add di,ax

        mov al,cl           ;字符颜色
        copy:
            mov cl,ds:[si]
            mov ch,0
            jcxz last           ;到字符串末尾就返回
            mov byte ptr es:[di],cl
            mov byte ptr es:[di+1],al
            inc si
            add di,2
            loop copy

        last:
            pop di
            pop si
            pop cx
            pop dx

        ret

code ends

end start

运行结果:
在这里插入图片描述
2、解决除法溢出问题

assume cs:code

;代码段
code segment

    start:
        mov ax,4240H
        mov dx,000FH
        mov cx,0AH
        call divdw

        mov ax,4c00H
        int 21H

    divdw:
        push ax

        mov ax,dx
        mov dx,0
        div cx     
        mov bx,ax  

        pop ax     

        div cx    
        mov cx,dx
        mov dx,bx

        ret 

code ends

end start

这题纯是在网上抄的,公式看不明白,根据网上代码理解如下
X:被除数,范围:[0,FFFFFFFF]
N:除数,范围:[0,FFFF]
H:X高16位,范围:[0,FFFF]
L:X低16位,范围:[0,FFFF]
+:运算符,表示双字节的高16位和低16位的整体
int():描述性运算符,取商
rem():描述性运算符,取余数

X/N的商 = int(H/N) + int((rem(H/N)+L)/N)
X/N的余 = rem((rem(H/N)+L)/N)
按照这个式子应该可以写出来,至于问为什么,我也不知道

运行结果:
在这里插入图片描述
在这里插入图片描述
3、数值显示
(1)先是固定值在ax中

assume cs:code, ds:data, ss:stack

data segment
    dw 16 dup(0)
data ends

stack segment
    dw 16 dup(0)
stack ends

;代码段
code segment

    start:
        mov ax,12666
        mov bx,data
        mov ds,bx
        mov si,0
        call dtoc

        mov dh,9
        mov dl,3
        mov cl,4
        call show_str
        
        over:
            mov ax,4c00H
            int 21H

    dtoc:
        push bx
        push di
        push dx
        push si
        push cx
        push ss
        push sp

        mov bx,stack
        mov bx,10
        mov di,0

        pushs:
            mov dx,0
            div bx
            add dx,30H
            push dx
            mov cx,ax
            inc di
            jcxz strend
            jmp short pushs

        strend:
            mov cx,di
            moves:
                pop ax
                mov byte ptr ds:[si],al
                inc si
                loop moves
            mov ax,0
            mov byte ptr ds:[si],al

            pop sp
            pop ss
            pop cx
            pop si
            pop dx
            pop di
            pop bx

        ret

    show_str:
        push dx
        push cx
        push si
        push di

        mov ax,0B800H
        mov es,ax

        ;计算行地址
        sub dh,1
        mov al,dh
        mov bl,0A0H
        mul bl
        mov di,ax

        ;加上列地址
        mov al,2
        mul dl
        add di,ax

        mov al,cl           ;字符颜色
        copy:
            mov cl,ds:[si]
            mov ch,0
            jcxz last           ;到字符串末尾就返回
            mov byte ptr es:[di],cl
            mov byte ptr es:[di+1],al
            inc si
            add di,2
            loop copy

        last:
            pop di
            pop si
            pop cx
            pop dx

        ret
code ends

end start

运行结果:
在这里插入图片描述
(2)然后是值在数据段中
利用前面已经写好的两个子程序,每次将数据段中的新值赋给ax,调用dtoc完成字符串转换,然后将show_str的字符串数据段改一下就行了,但是要注意各个寄存器值的变化,除了特殊需要,将子程序用到的寄存器都进行压栈出栈处理!!!

assume cs:code, ds:data, ss:stack

;要显示的数字
data segment
    dw 123,12666,1,8,3,38
data ends

;存放转换后的字符串
string segment
    dw 16 dup(0)
string ends

;栈段
stack segment
    dw 16 dup(0)
stack ends

;代码段
code segment

    start:
        mov ax,data
        mov es,ax
        mov di,0        ;di - 表示要显示的数字的字节偏移
        mov dh,9        ;dh - 从第几行开始打印
    s:
        mov ax,es:[di]
        mov cx,ax
        jcxz over       ;cx为0就跳到over,直接返回
        mov bx,string   
        mov ds,bx
        mov si,0        ;si - 要转换数字的地址(dtoc中),也是打印字符串的首地址(show_str中)
        call dtoc       ;执行数字转字符串子程序

        mov dl,3        ;打印的列数
        mov cl,4        ;颜色
        call show_str   ;执行打印字符串子程序

        add dh,1        ;下一个字符串在下一行打印
        add di,2        ;由于是字型所以+2
        jmp s
        
        over:
            mov ax,4c00H
            int 21H

    dtoc:
        push bx
        push di
        push dx
        push si
        push cx
        push ss
        push sp

        mov bx,stack
        mov bx,10
        mov di,0

        pushs:
            mov dx,0
            div bx
            add dx,30H
            push dx
            mov cx,ax
            inc di
            jcxz strend
            jmp short pushs

        strend:
            mov cx,di
            moves:
                pop ax
                mov byte ptr ds:[si],al
                inc si
                loop moves
            mov ax,0
            mov byte ptr ds:[si],al

            pop sp
            pop ss
            pop cx
            pop si
            pop dx
            pop di
            pop bx

        ret


    show_str:
        push dx
        push cx
        push si
        push di
        push es

        mov ax,0B800H
        mov es,ax

        ;计算行地址
        sub dh,1
        mov al,dh
        mov bl,0A0H
        mul bl
        mov di,ax

        ;加上列地址
        sub dl,1
        mov al,2
        mul dl
        add di,ax

        mov al,cl           ;字符颜色
        copy:
            mov cl,ds:[si]
            mov ch,0
            jcxz last           ;到字符串末尾就返回
            mov byte ptr es:[di],cl
            mov byte ptr es:[di+1],al
            inc si
            add di,2
            loop copy

        last:
            pop es
            pop di
            pop si
            pop cx
            pop dx

        ret
code ends

end start

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值