yanghongchen666 发表于 2020-8-4 11:41:08

实验10一些想对走到这里的鱼友们说的话

assume cs:code

data segment
        db 10 dup(0)
data ends

code segment

start:        mov ax,12666
                mov bx,data
                mov si,0
                call dtoc
               
                mov dh,8        ;行
                mov dl,3        ;列
                mov cl,2        ;颜色
                call show_str
               
                mov ax,4c00H
                int 21h

;第一步定义一个栈空间,方便一会存放12666的10进制数据用
;第二步用div指令对数据进行取余
;第三步把余数+30h来获得相对应的十进制的数据               
;第四步用ret命令退出子程序
dtoc:
        push ax
        push bx
        push cx
        push si
        push dx

        mov ds,bx                ;data栈的地址通过bx寄存器传递给ds
        mov bx,10d                ;因为一会用12666除以10可以留出余数刚好也是12666
        mov sp,16                ;设置栈底
        mov bp,0
       
        mov cx,5                ;因为五个数据所以循环5次
        ;保存数据
s0:        div bx                        ;ax里的数据跟bx的数据相除,由于是16位余数存放在dx
        mov bx,ax                 ;得到的商赋给cx
        add dx,30H                ;把dx里面的余数+30就是对应的十进制
        push dx                 ;dx中的数据压入到栈顶,这样倒出数据刚好得到12666
        loop s0
       
        mov cx,0
        mov cx,5
        ;传输数据到目标内存空间
s1:        pop bx                                ;用bx来接收出栈的数据
        mov ds:,bx                 ;bx再把数据传给ds:中
        add si,2                        ;因为每次传入的是两个字节,所以每次si加2
        loop s1
       
        pop ax
        pop bx
        pop cx
        pop dx
        pop si
       
        ret                ;结束子程序
       

show_str:
                push cx
                push dx
                push si
                push ax

                ;准备工作
                mov bx,0
               
                mov al,0A0H                        ;显存每行的16进制的位置
                dec dh                                ;cpu是从0开始读取数据的,所以8行要减1
                mul dh                                ;8行乘每行0A0H得到行的偏移地址
                mov bx,ax                         ;bx存放行的偏移地址

                mov al,2                        ;每列两个字符
                mul dl                                 ;用每行的字符 * 总行数 = 列的偏移地址
                sub ax,2                        ;因为显存04-05是第3列的偏移地址
               
                add bx,ax                        ;把刚才列的偏移地址加到bx中
                mov di,0
               
                ;导入数据
                mov ax,0b800h               
                mov es,ax                        ;通过ax寄存器传给es显存的地址空间
               
                mov al,cl                        ;此时要把cl中存放颜色的传入al,因为cl跟ch要作为jcxz的判断条件
                mov ch,0
               
        s:        mov cl,ds:                ;用cl来接收ds:里面的内容
                jcxz ok
                mov es:,cl        ;此时用cl在把数据传入给es
                mov es:,al        ;用这种方式寻址传入颜色是因为,显存中奇数位是颜色属性。
               
                inc si                                ;每次寻找下一个字节的内容
                add di,2                        ;显存每次要存放两个字节,低位为ascii,高位为颜色属性,所以di加2
                jmp short s                 ;无判断转移跳转到标号为s地方,实现循环
               
       ok:       
                pop cx
                pop dx
                pop si
                pop ax
               
                ret                                        ;结束子程序       

code ends
end start





上面是自己写的10.3的代码,当时思考10.1挺久的大概思路知道要怎么写,但是行跟列死活没想明白,迫于无奈看了小甲鱼视频刚看到开头就恍然大悟用mul可以来算出来行跟列的具体地址,于是我就赶紧把10.1写完了。
10.2一直没看懂就看了视频就过了,但10.3感觉很有意思也不是很难所以就用自己的思路写完了,虽然是错的但我觉得也没有关系,成功是失败之母如果第一次就能写对的话我可能就不坐在这里了哈哈哈哈。
大致思路是对的,代码部分还是需要提升,错误的最大的地方就是逻辑,跟粗心。完全忘记了每次除完要用商接着除.

一眨眼就学到第10章了,很高兴能在鱼c论坛跟各位相遇,每个人上这个课都有自己的目的,就如51小甲鱼片尾所说的一样,可能这三个程序对有些人很难,不过坚持下来就会成功,如果有想放弃的朋友们请在忍一忍,已经走完2/3的路了,你不是一个人孤身学习而是有着能跨越千里的网友一同陪伴着你,有问题也会有大佬帮你解答!大家加油!奥利给!

人间凑数 发表于 2020-11-14 21:31:25

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
页: [1]
查看完整版本: 实验10一些想对走到这里的鱼友们说的话