王爽汇编语言-第十章实验

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


一.显示字符串

;第一行的起始位置是 B8000h, 第二行的起始位置B8a00h
;显存的起始位置是B8000h
;在我执行2.exe后空格向下(enter)会刷新一行显存页面,所以要想在执行2.exe后,在第一行显示内容.起始地址应该使用B80a0h,
;因为第一行总会乘上1.除非乘以0(结果会被enter,刷新掉), 所以起始位置使用B80ah
;该程序可以把以0结尾的字符串,输入到屏幕指定的行和列
assume cs:code

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

stack segment
          dw 16 dup(0)
stack ends

code segment
    start:   mov  dh, 8          ;行号, 输入行号
             mov  dl, 3          ;列号, 输入列号
             mov  cl, 2          ;颜色-绿色
             
             mov  ax, data
             mov  ds, ax         ;定位数据段
             mov di, 0

             mov  ax, stack      ;设置栈段地址
             mov  ss, ax
             mov  sp, 32
             
             mov ax, 0B800h      ;设置显存目标段
             mov es,ax

             call show_str       ;在屏幕的给点定行列,用给定颜色显示字符串

             mov  ax, 4c00h
             int  21h

    show_str:                   ;这个程序改变了ax, cx, si , di
            push ax
            push si
            push cx
           
            mov al, 0a0h    ;计算目标行
            mul dh
            mov si, ax
            
            mov al, 02h    ;计算目标列,列减1,是因为列是从0开始计算的,行不减,因为在执行程序的过程中,会刷新掉第1行,直接显示第2行
            sub dl, 01h
            mul dl
            add si, ax
            
            mov al, cl      ;颜色
            
showBeg1:   mov cl, ds:[di]     ;在ds处取出数据,写入现存
            mov ch, 0
            mov es:[si], cl
            jcxz showEnd1       ;如果cx = 0,说明遇见了字符串结尾符0, 我们跳出循环
            inc di              ;准备写出下一个字符
            inc si              ;递增到刚写入字符,的颜色内存(一个字节)
            mov es:[si], al     ;写入颜色
            inc si              ;准备接受下一个字符
            jmp short showBeg1  ;无条件跳转
            
            
showEnd1:   pop cx
            pop si
            pop ax

            ret
code ends

end start

二.解决除法溢出问题

;一个不会溢出的除法运算,被除数dword, 除数word
;结果: dx 高16位, ax 低16位, cx余数
;16位除法, ax存储商,dx存储余数
;16位乘法, dx存放高位,ax存放低位
assume cs:code

stack segment
            dw 0,0,0,0,0,0,0,0
stack ends

code segment
      start:mov  ax, stack
            mov  ss, ax
            mov  sp, 10h

            mov  ax, 4240h
            mov  dx, 000FH
            mov  cx, 0AH
        
            call divdw

            mov  ax, 4c00h
            int  21h

  
      divdw:
            push ax
            mov  ax,dx
            xor  dx,dx; 清0
            div  cx
            pop  bx 
            push ax;存入商,存入L, 这里的余数
            push bx

            mov  ax,dx  ;rem(i) * 65535
            mov  bx,256 ;乘法这里的乘法,要乘以65535,16位的数不能放下65535, 使用了巧妙的方法乘以两次256
            mul  bx
            mul  bx
            pop  bx
            add  ax,bx  ;rem(i) * 65535 + L ? (这里为何在低位加上bx,会进位到,dx吗?也许会
            div  cx     ;(rem(i) * 65535 + L) /N 
            mov  cx,dx  ;保存余数, 余数只能由(rem(i) * 65535 + L) /N 产生
            pop  dx
            push ax
            mov  ax,dx
            mov  bx,256 ;int(H / N)*65536
            mul  bx
            mul  bx
            pop  bx     
            add  ax,bx  ;int(H / N)*65536 + (rem(i) * 65535 + L) /N 
            ret


code ends

end   start

3. 数值显示

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

data segment
           dw 123, 12666, 11, 12, 2002, 1
           db 32 dup(0)
data ends

stack segment
            dw 32 dup(0)
stack ends

code segment
      start:   
               mov  bx, data
               mov  ds, bx           ;定位数据段
               mov  di, 0
               mov  si, 12
             
           
               mov  bx, stack        ;设置栈段地址
               mov  ss, bx
               mov  sp, 32

               mov cx, 6      ;循环6次以此处理6个数字
       dt_s1:  
               call dtoc
               loop dt_s1

               
                mov  dh, 8          ;行号, 输入行号
                mov  dl, 3          ;列号, 输入列号
                mov  cl, 2          ;颜色-绿色

                mov ax, 0B800h      ;设置显存目标段
                mov es,ax

                call show_str       ;在屏幕的给点定行列,用给定颜色显示字符串

                mov ax, 04c00h
                int 21h
;-------------------------------------------------------------------------------
       dtoc:   
               push ax
               push cx
               push bx
               push dx
               
               
               mov ax,ds:[di]       ;被除数
               add di, 2
               mov bx, 0            ;存储位数
               
      dt_beg: 
               mov dx, 0
               mov cx, 10
               div cx
               mov cx ,ax
               inc bx
               add dx,030h
               push dx
               jcxz dt_end
               jmp short dt_beg

      dt_end:  mov cx, bx
               
     dt_lo:    pop ds:[si]
               inc si
               loop dt_lo 

               pop dx
               pop bx
               pop cx
               pop ax
               ret         
;-------------------------------------------------------------------------------
show_str:                   ;这个程序改变了ax, cx, si , di
            push ax
            push si
            push cx
           
            mov al, 0a0h    ;计算目标行
            mul dh
            mov si, ax
            
            mov al, 02h    ;计算目标列,列减1,是因为列是从0开始计算的,行不减,因为在执行程序的过程中,会刷新掉第1行,直接显示第2行
            sub dl, 01h
            mul dl
            add si, ax
            
            mov al, cl      ;颜色
            
showBeg1:   mov cl, ds:[di]     ;在ds处取出数据,写入现存
            mov ch, 0
            mov es:[si], cl
            jcxz showEnd1       ;如果cx = 0,说明遇见了字符串结尾符0, 我们跳出循环
            inc di              ;准备写出下一个字符
            inc si              ;递增到刚写入字符,的颜色内存(一个字节)
            mov es:[si], al     ;写入颜色
            inc si              ;准备接受下一个字符
            jmp short showBeg1  ;无条件跳转
            
            
showEnd1:   pop cx
            pop si
            pop ax

            ret
;-------------------------------------------------------------------------------
code ends
end start

转载自网络

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十七溯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值