shuiyu 发表于 2017-9-22 23:07:17

《零基础入门学习汇编语言》实验十

本帖最后由 shuiyu 于 2017-9-23 18:06 编辑

越努力,越幸运。欢迎大家来看我的笔记{:10_297:} 小白刚学,不对的请各位大佬指正,谢谢{:10_254:}

实验十

(一)
这是小甲鱼给出的答案,我也在里面做了一些注释(大致不难主要是能转过那个弯{:5_109:} )


(二)
这题的难点:
(1)主要是对题目给出的公式理解就好办,我来说一说我的理解;公式计算的结果其实并不是一个具体得结果,它在完成的过程中已经把一些结果得到了;比如结果的高16位和余数在公式的前半部分就已经得到了,而结果的低十六位则是在公式的后半部分得到的,它们是分开的,不是一个整体!{:10_254:}
(2)还有就是那个“*65536”
65536代表的就是16位寄存器。
除法指令div(16位的):
可以将被除数抽象 理解为 :
dx,ax= 16位寄存器,16位寄存器 = 65536,65536
乘以65536,就相当于左移16位(即:一个16位寄存器)
代码中已经做了×65536的步骤了:
第一次div求得的商存入存入了bx中(这个是高位商):mov si,ax,
在第二次div结束后,将bx(高位商)转存到dx中:mov dx,si(这个就是x65536的步骤,因为它把商放出了dx(可理解为高位寄存器))。
说的比较个人化,希望能听得懂!
(一些细节请看图)


(三)
对于这一题我有三个版本{:10_266:}
(1)第一个版本:是在知道要转化多少个字符的前提下,自己赋值给了SI,确定字符进入data段的位置,让字符能够顺利的显示到屏幕上。
其实我想直接用div的,但是运行之后一直显示除法溢出(但是我们的这个除法好像溢出不了吧{:10_258:} ),后来我只能调用防除法溢出daoc子程序喽。没想到有奇效!!
代码解析:
mov dx,0                ;因为被除数是12666嘛,由于被除数是高16位数据和低16位数据构成,则低16位为12666,高十六位为0(为了避免高16位里有数值
                                影响到结果,所以只能赋值了)
mov si,4                ;因为我们知道有5个字符要显示到屏幕上,所以把值分别赋值到0,1,2,3,4,这五个单元中,而因为取出来的会倒序,所以我们倒着输入。
mov cx,0ah        ;除数10;
call divdw        ;调用子程序divdw,结果:CX存放余数
jcxz abc                ;当CX为0就跳转,也就是余数为0跳转。因为12666除到最后面余数是为0的。
后面的很简单,书上都有我就不解释了


(2)第二个版本:其实就是第一个版本的升级版,实现了自动判断有多少个字符{:5_106:}
代码解析啥的看图,里面有详细的解答:





(3)第三个版本就是小甲鱼给的答案了,这个应该不用我解释了吧
PS:d表示为十进制。







谢谢小甲鱼带来的视频教程,感谢!! {:10_303:}

本节结束,多谢览阅!
越努力,越幸运。谢谢大家来看我的笔记{:10_297:} 小白刚学,不对的请各位大佬指教,谢谢{:10_254:}

人间凑数 发表于 2020-11-14 21:28:27

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

data segment
dw 123,12666,1,8,3,0
db 40 dup(0)
data ends

stack segment
dw 16 dup(0)
stack ends

code segment
start:mov ax,data
      mov ds,ax         ;数据初始化
          mov ax,stack
          mov ss,ax
          mov sp,32         ;栈初始化
          
          
      mov si,0
          call far ptr dtoc
          mov si,12
          mov dh,11
      mov dl,32
          mov cl,04h          ;定义函数的输入值
          call show_str
          
          mov ax,4c00H
          int 21h

show_str:      ;显示字符串子程序

      mov ch,0
          push cx   ;将cl的数据放入栈中
          
          mov ax,0b800h
          mov es,ax   ;用es保存显示缓冲区的地址
          
          mov al,160
          mul dh
          mov bx,ax;行结果放到bx中
          
          mov al,2
          mul dl
          add bx,ax;行与列放到bx中
          pop dx      ;pop必须写到循环外边
        s:mov cl,ds:;为了与下面的jcxz配合当cx为0时跳出
          jcxz ok       
          mov ah,
      mov es:,ah
          mov es:,dl
      
      inc si
      add bx,2          
      jmp s
   ok:ret
   
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
   
dtoc:    ;数值显示
       mov di,12   ;定位余数的内存空间
       
b:   mov dx,0
   mov ax,ds:;将所要转换的数放入ax
       mov cx,ax         
       jcxz cde       ;此次是为了判断要转换的数是否为零
       
       mov bp,-1            ;为了确定数字长度
sss:
       mov cx,10       ;设置除数
       call divdw
       push cx
       inc bp
       inc cx      ;这个inc cx是关键因为loop运算时,先
                   ;会进行cx-1操作
       loopsss
       
       pop cx      ;将最后入栈的0出栈
       mov cx,bp
a:          ;将入栈的数据放到内存中
       pop dx
       add dl,30h
       mov ds:,dl
       inc di
       loop a
       
       add si,2       ;为下一个数据初始化
       mov bp,20h
       mov ds:,bp
       inc di       
       jmp b
       
cde: retf    ;为0则直接跳出
       
       
      
code ends

end start

freedomOO 发表于 2021-5-30 09:38:13

很厉害,我回去努力追上你的
{:5_109:}
页: [1]
查看完整版本: 《零基础入门学习汇编语言》实验十