鱼C论坛

 找回密码
 立即注册
查看: 3334|回复: 3

[汇编作业] 第十章检测实验及笔记

[复制链接]
发表于 2016-1-7 22:58:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 yundi 于 2016-1-8 14:49 编辑

先来个实验10的第2题,解决除法溢出问题。

一张图理顺寄存器变化
无标题.png
;不溢出的除法子程序
;自己发明的表示法:(dx)(ax)/(cx)=(dx)(ax)...(cx)
assume cs:code
code segment
start:        mov dx,000fh
                mov ax,4240h
                mov cx,0ah
                call divdw

                mov ax,4c00h
                int 21h

divdw:
                ;1.先处理被除数高16位(dx)的除法                
                push bx;子程序用到的寄存器,先入栈保存
                push ax;被除数低16位(ax)后面要用,也保存到栈中
                mov ax,dx;因为除数(cx)16位,所以把高16位放到(ax)
                xor dx,dx;同时让(dx)为0
                div cx;然后相除(dx)(ax)/(cx)=(ax)...(dx)
                ;2.再处理被除数低16位(ax)的除法
                pop bx;被除数低16位出栈
                push ax;栈保存高16位除后的商
                ;现在的(dx)保存高16位除后的余数,正好下步可用
                ;公式中余数*65536,为何此处(dx)不乘?
                mov ax,bx
                div cx;(dx)(ax)/(cx)=(ax)...(dx),(ax)正好是结果的低16位
                mov cx,dx;结果的余数放入cx
                pop dx;取出高16位除后的商(dx),正好是结果的高16位
                ;公式中需要*65536,为何此处(dx)直接是结果?
                pop bx;取出bx原始值
                ret
code ends
end start

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-1-8 09:08:30 | 显示全部楼层
接着是实验10第1题
;子程序练习
;名称:show_str
;功能:按给定参数输出0结尾的字符串
assume cs:code
data segment
        db 'Welcome to masm!',0
data ends

code segment
start:        mov dh,8        ;行号
                        mov dl,3        ;列号
                        mov cl,2        ;颜色属性
                
                        mov ax,data
                        mov ds,ax
                        mov si,0        ;串首
                        call show_str  ;子程序
                        
                        mov ax,4c00h
                        int 21h
                        
show_str:
                        push ax
                        push es
                        
                        ;找偏移 (es):(dh)*160+(dl)*2
                        mov ax,0b800h
                        mov es,ax
                        mov al,160
                        mul dh        ;结果在(ax)
                        mov bx,ax
                        mov al,2
                        mul dl 
                        add bx,ax        ;偏移(bx)
                        
                        ;循环读字符并写入
                        mov ah,cl;先保存颜色属性
                        xor cx,cx;清空cx                
        s0:        mov cl,ds:[si];取出data中第si个字符
                        jcxz ok;(cx)=0如果字符为0跳到ok
                        mov al,cl;暂存字符
                        mov es:[bx],ax;此时 (ah)=颜色属性,(al)=字符,将其保存到b800:偏移 中
                        inc si;下个字符
                        add bx,2;下个显存位置
                        jmp short s0
                        
        ok:        pop es
                        pop ax
                        ret
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-9 14:45:05 | 显示全部楼层
实验10的第3题,代码越来越长。不知到win32汇编是啥状况。
;名称:dtoc
;功能:将word型数据变为十进制字符串,0结尾
;参数:(ax) = word型数据
;                ds:si 串首

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
                mov si,0
                call show_str;调用输出子程序
                
                mov ax,4c00h
                int 21h
                
dtoc:        
                push cx
s0:                mov cx,ax
                jcxz ok1;被除数为0表示循环结束,跳出
                mov bx,10;12666/10=1266>256,商要用(ax)保存,所以除数要16位(bx),不能(bl)
                xor dx,dx;12666<65536,除数16位,则被除数必须用到(dx),12666<65536,(dx)置0即可
                div bx;除后的结果 (ax)...(dx)
                push dx;保存余数,并将(ax)作为下次循环的被除数
                inc si;记录循环次数,求得字符串长度
                jmp short s0                
ok1:        mov cx,si
                xor si,si
s1:                pop ds:[si];依次出栈,将字符串顺序保存到ds:[si]中
                mov bl,30h
                add ds:[si],bl;数值转换为对应ASCII码
                inc si
                loop s1
                mov ds:[si],cx;将0保存到字符串结尾
                pop cx
                ret

show_str:;输出字符串子程序
                push ax
                push es
                mov ax,0b800h
                mov es,ax
                mov al,160
                mul dh
                mov bx,ax
                mov al,2
                mul dl
                add bx,ax                
                mov ah,cl
                xor cx,cx
s2:                mov cl,ds:[si]
                jcxz ok2
                mov al,cl
                mov es:[bx],ax
                inc si
                add bx,2
                jmp short s2
ok2:        pop es
                pop ax
                ret
                
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-5 17:02:21 | 显示全部楼层
ret                 用栈中数据修改ip        相当于 pop ip
retf                用栈中数据修改cs和ip        相当于 pop cs , pop ip



call                将当前ip 或 cs,ip入栈,然后跳转
1.    call 标号                                        相当于 push ip , jmp near ptr 标号
2.    call far ptr 标号                                相当于 push ip , jmp far ptr 标号
3.    call 16位reg                                相当于 push ip , jmp 16位reg
4.    call word ptr 内存单元地址        相当于 push ip , jmp word ptr 内存单元地址(2字节)
5.    call dword ptr 内存单元地址        相当于 push cs , push ip , jmp dword ptr 内存单元地址(4字节)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-26 14:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表