王爽汇编第二版实验10(整理)
来源:互联网 发布:网络编程学校 编辑:程序博客网 时间:2024/05/17 21:54
1.
;--------------------------------------------------------------------------------------
show_str:
;push指令保护子程序用到的寄存器
push bx
push cx
push dx
push si
push di
;指定显存区域
mov ax,0b800h
mov es,ax
;初始化行
mov ax,0a0h
dec dh
mul dh
mov bx,ax
;初始化列
mov ax,2
mul dl
mov di,ax
;将字符属性存入AH中
mov ah,cl
mov cx,16
;开始逐字符显示
s:
mov al,[si] ;源地址DS:SI指向数据段字符
cmp al,0 ;如果遇到0,则表示循环结束跳至ok处退出子程序
jz ok
mov es:[bx+di],ax ;目标地址ES:[BX+DI],AH=属性,AL=字符
inc si ;指向数据段下一个字符
add di,2 ;指向下一列
loop s ;如果CX≠0,继续循环
ok:
;恢复保护的寄存器
pop di
pop si
pop dx
pop cx
pop bx
;返回调用
ret
2.
assume cs:code
stack segment
dw 8 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,4240h ;被除数为000f4240H
mov dx,0fh
mov cx,0ah ;除数为0aH
call divdw ;int(H/N)
mov ax,4c00h
int 21h
divdw: push ax
mov ax,dx ;因为此时要做的是16位的除法,所以要设置AX,DX。根据公式这里做的是被除数的高位除以除数,被除数的高位为0FH,放到在16位除法中就应该是dx=0000h,ax=000fh
mov dx,0
div cx
mov bx,ax ;16位除法完后商会保存在ax中,我们先把高位除以除数的商保存在bx中
pop ax ;把被除数的低位从栈中取出
div cx ;这一步是关键,很多人不明白公式的后半段[rem(H/N)*65536+L]/N,在这我跟大家解释一 下,65536是10进制数,转换为16进制也就是10000.
;这里很多人要问,我们并没有用高位的余数*10000H+低位,而是直接用低位当被除数直接开始除法了!类似与L/N了,我想说你错了!因为在高位的除法中它的余数直接保留在DX中,而在低位除法中,DX正是这次除法的高位!
;也就是说,rem(H/N)*10000H这一步我们已经做了,这段公式不就说让我们把高位的余数放到高位吗?然后再加上低位组成一个新的被除数再除以除数[rem(H/N)*65536+L]这段公式的目的并不是要我们把数值相加,而是让我们完成一个32位的被除数,也就是用原始被除数的余数与原始被除数低位凑成一个完整的数如:设rem(H/N)值为0006H,L=4240H,这个数应该是00064240H
mov cx,dx
mov dx,bx
ret
code ends
end start
3.
第10章实验10.3 数值显示 (带详细注释);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;名称: dtoc
;功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符.
;参数:(ax)=word型数据
; ds:si指向字符串的首地址
;返回: 无
;应用举例:编程将数据12666以十进制的形式在屏幕的8行3列,用绿色显示
;出来.在显示时我们调用本次实验中的第一个子程序show_str.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;author:chinaljg
;time:2011年1月22日
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 ;调用完后,ds:si应指向data段中的以0结尾的字符串
mov dh,8 ;提供入口参数8行
mov dl,3 ;提供入口参数3列
mov cl,2 ;提供入口参数绿色
mov si,0 ;ds:si指向字符串首地址
call show_str ;调用子程序显示ds:si指向的以0结尾的字符串
mov ax,4c00h ;程序正常返回
int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;名称: dtoc
;功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符.
;参数:(ax)=word型数据
; ds:si指向字符串的首地址
;返回: 无
;应用举例:编程将数据12666以十进制的形式在屏幕的8行3列,用绿色显示
;出来.在显示时我们调用本次实验中的第一个子程序show_str.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dtoc:
push ax ;子程序调用的寄存器入栈
push bx ;子程序调用的寄存器入栈
push cx ;子程序调用的寄存器入栈
push dx ;子程序调用的寄存器入栈
push ds ;子程序调用的寄存器入栈
mov dx,0
mov bx,0ah
div bx ;用dxax/bx 16位除法,dx放余数,ax放商,ax是提供的入口参数
add dx,30h ;把数据码转变为ASCII码
push dx ;入栈
mov cx,ax
jcxz savedata
call dtoc ;通过递归就不用考虑出栈的数量.考虑:在那种情况下用递归?(除法取余)
savedata:
;第一次:31 00
;第二次:31 32 00
;第三次:31 32 36 00
;......
pop dx
mov ds:[si],dx
inc si
mov byte ptr ds:[si],0
pop ds ;子程序调用的寄存器出栈
pop dx ;子程序调用的寄存器出栈
pop cx ;子程序调用的寄存器出栈
pop bx ;子程序调用的寄存器出栈
pop ax ;子程序调用的寄存器出栈
ret ;递归后,ret返回到了savedata标号处,最后一层ret才返回到mov dh,8处.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;名称:show_str
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串.
;参数:(dh)=行号(取值范围0-24),(dl)=列号(取值范围0-79).
; (cl)=颜色, ds:si指向字符串的首地址
;返回:无
;应用举例:在屏幕的8行3列,用绿色显示data段中的字符串.
show_str:
push ax ;子程序用到的寄存器入栈
push bx ;子程序用到的寄存器入栈
push cx ;子程序用到的寄存器入栈
push dx ;子程序用到的寄存器入栈
push ds ;子程序用到的寄存器入栈
push si ;子程序用到的寄存器入栈
push es ;子程序用到的寄存器入栈
push di ;子程序用到的寄存器入栈
mov ax,0b800h
mov es,ax
mov di,0 ;es:di指向显示缓存区,用来显示字符串
;根据入口参数行号和列号计算显存中的地址
mov al,160 ;8位乘法,一个默认放在al中,另一个放在8位的reg或内存单元,结果默认放在ax中,思考:ah不用清0的原因。
mul dh
add ax,160 ;加上第0行,因为行号是从0开始的。行号是8指的其实是第9行
add dl,dl ;一个字符占2列,一列放字符,另一列放这个字符的颜色属性,请思考:这儿为什么不加第0列?
mov dh,0 ; ax与cl中的数相加就是显存地址,但是ax与cl长度不对等,不能直接相加
add ax,dx ;ax中存放的就是8行3列所对应的显存地址的开始位置
mov di,ax ;用di作为显存地址的偏移量
show_str_display:
push cx ;下面要用cx来做判断,为了不破坏原数据,入栈
mov cl,ds:[si] ;将字符串中的字符传送到显示缓冲区
mov es:[di],cl
mov ch,0 ;构造cx用来判断是否到字符串的结束符‘0’
jcxz show_str_ok ;字符已经显示完毕,返回
pop cx ;没有到字符串结尾,出栈用来设置字符颜色。思考:若到字符串结尾了,你的出栈指令写在哪?
mov es:[di].1,cl ;给字符设置颜色属性
inc si ;下一个字符
add di,2 ;下一个用来显示字符的显存地址(一个字符要想显示要占2个显存地址,一个是字符,另一个是颜色)
jmp short show_str_display
show_str_ok:
pop cx ;到字符串结尾,出栈。以免影响子程序返回的ip
pop di ;子程序用到的寄存器出栈,注意顺序
pop es ;子程序用到的寄存器出栈,注意顺序
pop si ;子程序用到的寄存器出栈,注意顺序
pop ds ;子程序用到的寄存器出栈,注意顺序
pop dx ;子程序用到的寄存器出栈,注意顺序
pop cx ;子程序用到的寄存器出栈,注意顺序
pop bx ;子程序用到的寄存器出栈,注意顺序
pop ax ;子程序用到的寄存器出栈,注意顺序
ret ;返回
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
code ends
end start
- 王爽汇编第二版实验10(整理)
- 王爽汇编第二版实验9(整理)
- 王爽汇编第二版实验16(整理)
- 王爽汇编第二版实验10
- 王爽汇编第二版实验4
- 王爽汇编第二版实验5
- 王爽汇编第二版实验11
- 王爽汇编第二版实验12
- 王爽汇编第二版检测点15.1(整理)
- 王爽汇编语言第二版实验4(整理)
- 王爽汇编第二版第7章实验6
- 王爽汇编第二版第8章实验7
- 王爽汇编第三版 实验七
- 王爽汇编第二版第10章
- 王爽汇编第二版 第一章答案
- 王爽汇编第二版第二章答案
- 王爽汇编实验9
- 王爽汇编实验9
- fedora运行魔兽争霸
- python源代码现成重用大全
- servletContext 和 application 的区别
- ARM的股票表现不错 @美东时间:9月1日 07:01:47
- 最常用的设计模式 .
- 王爽汇编第二版实验10(整理)
- Looper和Handler
- android中Logcat的TAG过滤
- 获取当前经纬度方法
- poj2516
- 框架入门1-struts2准备与原理
- Android开发:休眠唤醒或开机后cmwap/cmnet网络不能连接的解决办法
- 学习字节流
- 源代码