经过今天晚上对另外一个博主的课程设计1的代码进行了详细的分析,我把相关的注释加了上去,从头到尾明白了作者的设计思想,实在是受益匪浅,在使用汇编语言编程的时候应该注意尽量以最少使用寄存器来达到目的,为了最少使用寄存器,可以采用段内使用stack,开辟栈的方法来设计不同的动作。
在进入段前保存数据的时候要注意尽量不使用寄存器保存数据,因为很可能后来寄存器不够用,那么不使用寄存器的最好的解决办法就是使用栈,使用栈相对于使用内存而言要保护性更好。要注意压栈和弹栈的顺序问题。
另外还有一点就是明白了可以在汇编中开辟一段地址当作变量来使用,从而方便自己的开发。
分析的代码和注释如下:
assume cs:code
asc segment
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1;------ds:[15]为行变量
asc ends
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2369,8000,16000,24486,50065,97479,140417,197514
dd 345980,590872,803530,1183000,1843000,2759000,3753000,4649000,59307000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends;------es
stack segment
db 32 dup (0)
stack ends ;----ss
code segment
start:
mov ax,data ;将data的数据段信息传入es为下一步做准备
mov es,ax
mov ax,asc ;一个变量,最后一个元素改变程序的偏移量的
mov ds,ax
mov ax,stack ;准备了一个栈
mov ss,ax
mov sp,32 ;栈信息
mov si,0
mov di,0
mov cx,21 ;21年
s:
push cx
mov ax,es:[si];把data中的数据放在ds:[0][1]中放入 19 一共16个字节
mov ds:[0],ax
mov ax,es:[si+2];将data中的 ds:[2][3]放入75 一共16个字节
mov ds:[2],ax
mov byte ptr ds:[4],0 ;将第4个位置设置为0,目的是为了进行jcxz跳转
mov dh,ds:[15] ;变化位置的
mov dl,0 ;变换位置的
mov cl,2 ;指示颜色
call show0str ;显示年份
mov ax,es:84[si] ;设置dd的起始地址16,22....就是其中一个数字的代表
mov dx,es:86[si] ;一共4个单位代表数字
call dtoc
mov dh,ds:[15]
mov dl,9
mov cl,3
call show0str ;显示收入
mov ax,es:168[di]
mov dx,0
call dtoc
mov dh,ds:[15]
mov dl,39
mov cl,4
call show0str ;显示人数
mov ax,es:84[si]
mov dx,es:86[si]
div word ptr es:168[di]
sub dx,dx
call dtoc
mov dh,ds:[15]
mov dl,69
mov cl,5
call show0str ;计算并显示人均
pop cx
add si,4
add di,2
inc byte ptr ds:[15]
loop s
mov ax,4c00h
int 21h
dtoc:;把所有可能用到的寄存器进栈,之后出来前再把所有的寄存器出栈
push ax
push bx
push cx
push dx
push si
push di
mov di,0
dtocnum:
mov cx,10 ;设置除数是10
call divdw
add cx,30h ;将16进制数字变成10进制
inc di ;设置下一步的循环次数
push cx ;把10进制的cx(余数)压入程序,此时是低位余数进入
mov bx,ax ;把低位商保存在bx中
add ax,dx ;dx是高位商,把低位商和高位商相加,-》
mov cx,ax ;一直到商的和为0结束
jcxz dtocend
mov ax,bx ;把低位商还原
jmp dtocnum
dtocend:
mov cx,di ;设置下一步出栈的循环次数
mov si,0
dtoccopy:
pop [si]
inc si
loop dtoccopy
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
divdw:
push bx
mov bx,ax ;ax储存的是低16位数字,dx中储存高16位数字
mov ax,dx
sub dx,dx ;等同于mov dx,0
div cx
push ax ;ax储存的是高位商,还有dx是存储的余数
mov ax,bx
div cx
mov cx,dx ;把余数给了cx,ax是低位商
pop dx ;把高位商放在dx中
pop bx
ret
show0str:
push ax ;保存在主程序的任何信息,可以这样设计就是把所有的都给压栈
push bx
push cx
push dx
push es
push si
mov al,160 ;从这里开始是showOstr程序的主体部分,此处为定位单位信息中的
mul dh ;结果存储在ax中
mov bx,ax
mov al,2
mul dl
add bx,ax ;定位信息一直持续到此处
mov ax,0b800h ;这一句和下一句是设置屏幕显示位置是在首页,设置了段地址
mov es,ax
mov al,cl ;在这里cl中存储的是颜色的信息,在下一步要将数字信息传给cl,高位颜色信息,低位是数字信息
mov ch,0
mov si,0 ;对应的是变量ds中的偏移地址
show0num: ;此处是打印信息,一次一个字符的打印,例如1975,共需要4次循环
mov cl,[si]
mov ch,0
jcxz show0ok ;只是0的话就不打印直接进入showOok中
mov ch,al
mov es:[bx],cx;将cx中的内容打印出来
inc si ;打印下一个单元1975第一次打印1第二次准备打印9
add bx,2 ;向右移动一个单元
jmp show0num
show0ok:
pop si
pop es
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start
- [fpamc] 不做伸手党 02/28 14:20
- [kyolxs] windows 下的汇编。 不知道什么时候我才有能力看? 继续前行! 共勉! 07/19 21:10
- [1035802659] 谢了 05/05 14:14
- [游客] 收藏了 04/21 16:09
- [游客] 这就是你丫的人机交互 06/11 20:19
- [maxm] 研究研究你这个dtoc 05/22 20:45
- [游客] 强,得赶紧学习追赶了。 04/29 10:30
- [findufo] 收藏了 04/25 15:39
- [lanchong317] 我粘贴了 04/25 13:25
- [loswer] 建议不要看谭浩强的《C语言程序设计》的书,太垃圾了。语言结构不严谨,代码格式乱七八糟 还是看由C语 04/11 18:34
- [wangping198611] 收到了,呵呵,谢谢。 04/01 09:22
- [mouse] [ wangping198611 发表于 2009-03-23 11:43 ] 03/31 10:28