实验10一些想对走到这里的鱼友们说的话
assume cs:codedata 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的路了,你不是一个人孤身学习而是有着能跨越千里的网友一同陪伴着你,有问题也会有大佬帮你解答!大家加油!奥利给! 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]