关于实验10(3)
实验10(3)我用了1天多的时间才搞定,也没看答案,原因有二:一是自己的思路容易受答案思路干扰,二是看答案就必须按照答案思路去理解,也很累人的。自己搞定之后再看答案比较,应该更容易理解答案。当然,最关键的是要自己能做出来,至于思路是不是简介并不重要,因为随着经验增加,对汇编语言的理解
会越来越深,思路自然会越来越精。
开始时,本人试图把数据段同时当作栈段,但是因为后续思路没厘清,就放弃了。本人的方法是基于知道12666这个数的位数来弄的。
现把本人代码共享。下一步是考虑问题扩展,即把12666扩大到32bit位数据,使用dx和ax联合存储,数字不固定。
assume cs:code
data segment
db 10 dup(0)
data ends
code segment
start: mov ax,12666
mov bx,data
mov ds,bx
mov si,0
call dtoc
mov dh,8;8行
mov dl,3;3列
mov cl,2;字符属性
call show_str
mov ax,4c00h
int 21h
dtoc: mov si,5;用来指向字节数据偏移地址,初始指向索引位置5,然后从索引位置4开始依次向低地址存放数字
mov bx,10;设置除数10给bx,每次去除被除数,取余数即为要的数字
mov cx,5;设置循环次数
s: ;考虑到al长度可能不够保存商,所以被除数用dx+ax保存,除数用bx保存
;因为偏移地址从0索引开始,而当cx=0时循环结束。为了保证存储次数和
;循环次数一致,所以,si初始值为5,开始循环时,先把si自减一次。
dec si;
mov dx,0
div bx;除法结果:ax存商,也即是下一步的被除数,dx保存余数,即要取的数字
add dl,30h;因为余数是一位数字,保存在dx寄存器的低8位dl中。再加30h转化为对应的ASCII码
mov ds:,dl;
loop s
ret
show_str: mov ax,0b800h;把显示段给附件段
mov es,ax
mov al,160;计算显示段偏移地址
mul dh
mov si,ax;此时si中存储的是第8行的首地址
mov al,2;每列占2个字节。计算3列的偏移地址,为方便下面传值,直接把3列的偏移地址加到si上
mul dl;dl中存储的是列数3
add si,ax;si定位到显示段的第8行第3列
mov al,cl;因下面要用到cx,所以先把cl中存的字符属性值给al
mov di,0;指向数据段起始字节偏移地址
mov cx,5;循环次数,把数字字符ASCII码移入显示段,同时赋予字符属性为2
t: push cx
mov dl,ds:
mov es:,dl;存入数字ASCII码
mov es:.1,al;存人字符属性
inc di
add si,2
pop cx
loop t
ret
code ends
end start
关于实验10(3)的代码分享与改进建议
感谢您分享关于实验10(3)的代码及思路!看得出您已经花了不少时间和精力去解决这个问题,并且有了自己的见解。下面我对您的代码和描述做一些整理并给出改进建议。
主要代码功能:
[*]将数字12666转换为字符并存储。
[*]在屏幕的第8行第3列显示这些字符。
代码注释与调整建议:
1. 使用更清晰的变量名可以提高代码的可读性。
2. 在dtoc转换过程中,可以考虑支持更大范围的数字。
以下是对原代码的结构化整理与注释:
assume cs:code
data segment
db 10 dup(0) ; 存储数字的字符转换
data ends
code segment
start:
mov ax, 12666 ; 初始化要转换的数字
mov bx, data
mov ds, bx ; 初始化数据段寄存器
mov si, 0
call dtoc ; 调用数字到字符的转换函数
mov dh, 8 ; 指定文本显示行
mov dl, 3 ; 指定文本显示列
mov cl, 2 ; 字符属性
call show_str ; 调用显示函数
mov ax, 4c00h ; 正常退出
int 21h
dtoc:
mov si, 5 ; 偏移地址指向转换结果末尾
mov bx, 10 ; 商的除数
mov cx, 5 ; 最大循环次数
convert_loop:
dec si
mov dx, 0
div bx ; AX除以BX, 余数在DX,商在AX
add dl, 30h ; 转换余数为ASCII字符并存储
mov ds:, dl
loop convert_loop
ret
show_str:
mov ax, 0b800h ; 显存段地址
mov es, ax
mov al, 160 ; 计算第8行起始地址
mul dh
mov si, ax
mov al, 2
mul dl
add si, ax ; 确定显示偏移地址
mov al, cl ; 获取字符属性
mov di, 0 ; 数据段起始偏移地址
mov cx, 5 ; 显示字符个数
display_loop:
push cx
mov dl, ds:
mov es:, dl; 显示字符
mov es:, al; 设定字符属性
inc di
add si, 2
pop cx
loop display_loop
ret
code ends
end start
进一步扩展:可以考虑将dtoc函数改进以支持32位数字转换。例如,可以分别处理dx和ax,以处理最大位数。
再次感谢您的分享,希望对您进一步的扩展和理解有帮助!如果有任何问题,请随时询问。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]