. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验10第一题,各位挑下刺,看有没有改进空间  [待解决] 回复[ 4次 ]   点击[ 403次 ]  
xohome
[帖 主]   [ 发表时间:2011-10-08 17:30 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:2
注册日期:2010-11-24 11:04
程序:
assume cs:codesg

datasg segment
        db 'Welcome to masm!',0
datasg ends

codesg segment
start:
        mov dh,8
        mov dl,3
        mov cl,2
        mov ax,datasg
        mov ds,ax
        mov si,0
        call show_str
        mov ax,4C00H
        int 21H
show_str:
        push es
        push ax
        push bx
        push cx
        push dx
        push si
        mov ax,0B800H
        mov es,ax
        mov al,0A0H        ; 计算行偏移
        mul dh
        mov bx,ax
        add dl,dl        ; 计算列偏移
        add bx,ax        ; 累加行列偏移,确定显示地址
        mov ah,cl
        mov ch,0
show:        mov cl,[si]
        jcxz return
        mov al,cl
        mov es:[bx],ax
        inc si
        add bx,2
        jmp short show
return:        pop si
        pop dx
        pop cx
        pop bx
        pop ax
        pop es
        ret
codesg ends
end start
说明一点:
题目要求行的取值范围是(0~24)而显示缓冲区最大25行,也就说起始下标是0开始的,直接乘以0A0H则可算出行的偏移地址。 传入参数的8按照0为起始地址来看,正确的显示应该是第九行。 同理,3列应该显示在第四列。
xohome
[第1楼]   [ 回复时间:2011-10-08 23:01 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:2
注册日期:2010-11-24 11:04
继续发第二题:
assume cs:codeseg
codeseg segment
start:
        mov ax,4240H
        mov dx,000FH
        mov cx,0AH
        call divdw
        
        mov ax,4C00H
        int 21H
divdw:
        push bx   ;使用到的bx寄存器入栈
        push ax   ;将低十六位暂时入栈
        mov ax,dx ;运算高十六位,因为除数cx是十六位,所以被除数为32位,低位存放到ax中
        mov dx,0  ;将除法运算高位置零
        div cx    ; H/N 高十六位除法运算,商存储在ax中,余数在dx中
        mov bx,ax ; 将商临时存放到bx中
        pop ax    ; 将被除数低16位出栈,这一步完成rem(H/N)*65536+L,余数乘以65536就是将低16位ax置为高16位dx,pop ax将低位放入ax,等同加上L
        div cx
        
        mov cx,dx ; 将最后余数放入cx(题目要求)
        mov dx,bx ; 将临时变量bx中的值(高位)放入dx
        pop bx
        ret
codeseg ends
end start
结果:(dx)=0001H,(ax)=86A0H,(cx)=0
xohome
[第2楼]   [ 回复时间:2011-10-08 23:01 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:2
注册日期:2010-11-24 11:04
继续发第二题:
assume cs:codeseg
codeseg segment
start:
        mov ax,4240H
        mov dx,000FH
        mov cx,0AH
        call divdw
        
        mov ax,4C00H
        int 21H
divdw:
        push bx   ;使用到的bx寄存器入栈
        push ax   ;将低十六位暂时入栈
        mov ax,dx ;运算高十六位,因为除数cx是十六位,所以被除数为32位,低位存放到ax中
        mov dx,0  ;将除法运算高位置零
        div cx    ; H/N 高十六位除法运算,商存储在ax中,余数在dx中
        mov bx,ax ; 将商临时存放到bx中
        pop ax    ; 将被除数低16位出栈,这一步完成rem(H/N)*65536+L,余数乘以65536就是将低16位ax置为高16位dx,pop ax将低位放入ax,等同加上L
        div cx
        
        mov cx,dx ; 将最后余数放入cx(题目要求)
        mov dx,bx ; 将临时变量bx中的值(高位)放入dx
        pop bx
        ret
codeseg ends
end start
结果:(dx)=0001H,(ax)=86A0H,(cx)=0
xohome
[第3楼]   [ 回复时间:2011-10-09 15:33 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:2
注册日期:2010-11-24 11:04
第一题有一行错了
add bx,ax        ; 累加行列偏移,确定显示地址
应该修改为:
and dh,0H
add bx,dx
xohome
[第4楼]   [ 回复时间:2011-10-11 18:55 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:2
注册日期:2010-11-24 11:04
第三题想了N久,其它都简单,主要是转换为十进制后的倒序问题,用栈来倒序是简单,但容易出问题,不说栈操作的是两个字节,而且还让子程序依赖栈,总之这种方法不理想。
那剩余的方法就是用寄存器了,在si存入0的时候其实就得出了数字的空间长度,知道长度,起始位置,那倒序操作最多循环N/2+1次,下面是我的代码(通过测试):
; 实验十(3)
; 名称:dtoc
; 功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符。
; 参数:(ax)=word型数据
;        ds:si指向字符串的首地址
; 范围:无
; 应用举例:编程,将数据12666以十进制的形式在屏幕的8行3列,用绿色显示出来。
assume cs:codesg
datasg segment
        db 10 dup (0)
datasg ends
codesg segment
start:
        mov ax,12666
        mov bx,datasg
        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:        
        push ax
        push dx
        push bx
        push cx
        push si
        push di
        mov di,si
        mov bx,10
tran:        and dx,0H
        div bx
        mov cx,ax
        add dl,30H
        mov [si],dl
        inc si
        jcxz sort
        jmp short tran
sort:        mov byte ptr [si],0
        mov ax,si
        mov bl,2
        div bl
        dec si
        mov cl,ah
        jcxz pp
        inc al
pp:        mov cl,al
swap:        mov al,[di]
        mov ah,[si]
        mov [si],al
        mov [di],ah
        inc di
        dec si
        loop swap
        pop di
        pop si
        pop cx
        pop bx
        pop dx
        pop ax
        ret
; 显示字符串
show_str:
        push es
        push ax
        push bx
        push cx
        push dx
        push si
        mov ax,0B800H
        mov es,ax
        mov al,0A0H        ; 计算行偏移
        mul dh
        mov bx,ax
        add dl,dl        ; 计算列偏移
        and dh,0H
        add bx,dx        ; 累加行列偏移,确定显示地址
        mov ah,cl
        mov ch,0
show:        mov cl,[si]
        jcxz return
        mov al,cl
        mov es:[bx],ax
        inc si
        add bx,2
        jmp short show
return:        pop si
        pop dx
        pop cx
        pop bx
        pop ax
        pop es
        ret
codesg ends
end start
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved