- [cutebe] 相当牛,这个苦思冥想也值了。^_^ 11/30 00:00
- [parse] 如果忽略消息循环,那么操作系统加载的程序很快就执行完了,就像DOS程序一闪而过,所以CPU会空闲下来 06/30 09:04
- [游客] 楼主好厉害,挺一下! 01/19 08:43
- [游客] 很不错。 01/04 18:36
- [chinatree] 潜力贴留名,沙发。 11/08 12:58
- [youthangel] 恩,这次对了 10/30 18:56
- [fpamc] mov bx,18 在这条指令的上边是不是要加一条sub dx,dx? 10/30 10:03
- [fpamc] 对的 10/27 11:19
- [fpamc] 对的 10/27 09:00
- [fpamc] 哦,对不起,看错了。实验13也有一个7ch中断 10/27 08:52
- [游客] 现在急需一个汇编大作业。。。。。。可以么。。。。。如果今天之内看见留言 就加 1765496715 12/28 16:52
- [youthangel] 这算是对我学习的鼓励吗?谢谢!咱们这样交流就可以了 10/11 15:48
- [fpamc] 多日观察,你的学习积极性挺高的。可以来我们群了。群号:75916434 10/11 10:58
[2012-10-14 10:39] 课程设计一
comment ;
这算是我写过的第一个汇编大程序了。虽然只有100多行,但这1区区一百行跟C的一百行可没法比。挺考验我对
代码的驾驭能力的。尤其是对子程序调用。
进步之处:
1、对整个程序的框架的把握还算到位,基本上是用子程序实现的
2、对现场的保护和恢复有的些许进步
不足之处:
1、代码的灵活性还不够,代码一直在生搬硬套
2、对汇编程序的调试能力有点弱,调成代码占用了整个工作的把部分时间
3、标号名称起的有点乱
4、最后的输出结果不够整齐,这个以后再做修改(我现在还没想到怎么弄,时间有点仓促)
下面开始贴代码……
课程设计一
算法描述:
1、调用实验七的程序,设置table的数据
2、从table段取数据传给deal子程序进行处理
3、在deal子程序里返回调用溢出子程序divdw把得到的余数入栈(为了逆置),把栈中数据给mydata段
4、利用deal把一行的数据处理完,调用show_str子程序,显示一行的数据
5、把以上的工作重复21次(有21年的数据)
;
assume cs:code,ds:data,ss:stack
data segment
;年份
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984'
db '1985','1986','1987','1988','1989', '1990','1991','1992','1993','1994','1995'
;收入
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;人数
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
;表格
table segment
db 21 dup('year summ ne ?? ')
table ends
;临时存储段192b
mydata segment
dw 16 dup(0) ;32个字节
mydata ends
;栈段 192d
stack segment
dw 4 dup (0) ;24个字节
stack ends
;代码段
;bx,dx,cx
code segment
start:
mov ax,mydata
mov ax,stack
mov ss,ax
mov sp ,10h ;初始化栈段
call settable ;设置表格
mov dh,3 ;行
mov dl,5 ;列
mov bx,0 ;bx控制table段的行
mov cx,21 ;循环21次
s:
mov si,0 ;记录一行的十进制数的个数
push dx
mov ax,table
mov ds,ax
mov ax,[bx]
mov dx,[bx+2] ;取出年份
mov bp,mydata ;年份就是按字符存储的直接显示
mov es,bp
sub ax,3030h
mov es:[si],ax
sub dx,3030h
mov es:[si+2],dx
mov al,20h
mov es:[si+4],al
add si,5
mov ax,[bx+5]
mov dx,[bx+7] ;取出收入
call deal
mov ax,table
mov ds,ax
mov ax,[bx+10] ;取出雇员数
mov dx,0fffh
call deal
mov ax,table
mov ds,ax
mov ax,[bx+13] ;取出人均收入
mov dx,0fffh
call deal
mov ax,21h
mov [si],al
;显示一行子程序
;dx控制显示位置,不能被其他子程序占用
mov ax,mydata
mov ds,ax
mov si,0 ;指定数据位置
pop dx
call show_str ;调用子程序
inc dh ;行加一
add bx,16 ;进入下一行
loop s
;暂停
mov ah,1
int 21h
;退出
mov ax,4c00h
int 21h
comment ;----------------显示子程序------------------------------
功能: 显示子程序
参数:DH 行,dl列 DS:[SI]数据位置
返回:无
;
show_str:
push di
push es
push ax ;保护现场
mov al,160
mul dh ;算出第dh行在显存中的位置
mov di,ax
mov al,2
mul dl ;算出第dl列在第dh行的第几个内存单元
add di,ax ;算出显存的开始单元
mov ax,0b800h
mov es,ax ;初始es
;开始显示
s1:
mov al,[si] ;取出要显示的字符
cmp al,21h ;判断是否是行结束符
je return ;是的话就返回的主程序
cmp al,20h ;判断是否是空格
je space ;是的话就空八个格
add al,30h ;不是空格,开始处理变成对应的ASCII
mov es:[di],al ;放入显存
mov al,2
mov es:[di+1],al ;设置显示属性
add di,2
sc:
inc si
jmp s1
space: ;处理空格
add di,16 ;空八个格
jmp sc
;显示结束
return:
pop ax ;恢复现场
pop es
pop di
ret
comment ;-----------------数据处理子程序----------------------------
功能:处理数据
参数: DX AX
返回:myData段中的一行数据
;调用除法子程序
;判断是否除尽
;没除尽,入栈,循环
;除尽了,放入temp段中 加上标志' '空格20h
;
deal:
;保护现场
push cx
push bx
;开始处理
mov bp,0 ;初始化计数器
cmp dx,0fffh ;判断是多少位的数据,其实这一步有点多余,16位的除法可以用32位的除法子程序处理
jne l
lows: ;16位的被除数处理
mov bx,10
call divw ;调用除法子程序
cmp ax,0 ;判断商是否为零
je lo
push bx ;把余数入栈
inc bp
jmp lows
lo:
push bx
inc bp
jmp same
l: ;32位的被除数处理
mov bx,10
call divdw ;调用除法子程序
cmp dx,0 ;判断商是否为零
je putdata
n0ax:
push cx ;把余数入栈
inc bp
jmp l
putdata:
cmp ax,0 ;判断商是否为零
jne n0ax
push cx
inc bp
;-----------------从栈到mydata-----------------
same:
mov ax,mydata
mov ds,ax
s0:
cmp bp,0
je bk
pop ax ;从栈中取数据
mov [si],al
inc si
dec bp
jmp s0
back:
;处理结束
pop bx
pop cx
;恢复现场
ret
bk:
mov al,20h ;加空格表示一个数结束如:16
mov [si],al
inc si
jmp back
;------------------子程序 16位的除法溢出--------------------------
comment ;
功能:解决16位除法溢出问题
参数:ax被除数,bh除数
返回:AX 商,bl余数
;
divw: ;15位的除法溢出
;保护现场
push dx
;开始运算
mov dl,al ;保存低位
mov al,ah
mov ah,0
div bl ;商在al中,余数在ah中
mov dh,al ;保存高位商
mov al,dl ;在次组成16位
div bl
mov bl,ah ;余数放在bl中
mov ah,dh ;商放在ax中
;运算结束,结果:商在ax中,余数在bl中
pop dx
;恢复现场
ret
;------------------子程序32位的除法溢出--------------------------
comment ;
功能:解决32位除法溢出问题
参数:dx ax被除数,bx除数
返回:DX AX 商,cx余数
;
divdw: ;32位的除法溢出
;保护现场
;开始运算
push ax ;把低位保存起来
mov ax,dx
mov dx,0
div bx ;高八位的商在ax中,余数在dx中
mov cx,ax ;把高位商给cx
pop ax ;低位出栈
div bx ;低位商在ax中,余数在dx中
xchg cx,dx ;dx和cx中的数据交换
;运算结束,结果:商在dx:ax中,余数在cx中
;恢复现场
ret
comment ;-------------设置表格--------------------------
功能:设置表格子程序
参数:无
返回:无
;
settable:
mov ax,data
mov ds,ax
mov bx,0 ;ds:bx->数据
mov si,168 ;ds:si->雇员人数
mov ax,table
mov es,ax
mov di,0 ;es:di->表格
mov cx,21 ;循环21次
s2:
;复制年份
mov ax,[bx]
mov dx,[bx+2]
mov es:[di],ax
mov es:[di+2],dx ;完成复制年份 四个字节
;复制收入
mov ax,[bx+84]
mov dx,[bx+86]
mov es:[di+5],ax
mov es:[di+7],dx ;完成收入的复制
div word ptr[si]
;将人均收入放入指定位置
mov es:[di+13],ax
;复制雇员数
mov ax,[si]
mov es:[di+10],ax ;完成雇员数的复制
add bx,4
add si,2
add di,10h
loop s2
ret
code ends
end start
这算是我写过的第一个汇编大程序了。虽然只有100多行,但这1区区一百行跟C的一百行可没法比。挺考验我对
代码的驾驭能力的。尤其是对子程序调用。
进步之处:
1、对整个程序的框架的把握还算到位,基本上是用子程序实现的
2、对现场的保护和恢复有的些许进步
不足之处:
1、代码的灵活性还不够,代码一直在生搬硬套
2、对汇编程序的调试能力有点弱,调成代码占用了整个工作的把部分时间
3、标号名称起的有点乱
4、最后的输出结果不够整齐,这个以后再做修改(我现在还没想到怎么弄,时间有点仓促)
下面开始贴代码……
课程设计一
算法描述:
1、调用实验七的程序,设置table的数据
2、从table段取数据传给deal子程序进行处理
3、在deal子程序里返回调用溢出子程序divdw把得到的余数入栈(为了逆置),把栈中数据给mydata段
4、利用deal把一行的数据处理完,调用show_str子程序,显示一行的数据
5、把以上的工作重复21次(有21年的数据)
;
assume cs:code,ds:data,ss:stack
data segment
;年份
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984'
db '1985','1986','1987','1988','1989', '1990','1991','1992','1993','1994','1995'
;收入
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;人数
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
;表格
table segment
db 21 dup('year summ ne ?? ')
table ends
;临时存储段192b
mydata segment
dw 16 dup(0) ;32个字节
mydata ends
;栈段 192d
stack segment
dw 4 dup (0) ;24个字节
stack ends
;代码段
;bx,dx,cx
code segment
start:
mov ax,mydata
mov ax,stack
mov ss,ax
mov sp ,10h ;初始化栈段
call settable ;设置表格
mov dh,3 ;行
mov dl,5 ;列
mov bx,0 ;bx控制table段的行
mov cx,21 ;循环21次
s:
mov si,0 ;记录一行的十进制数的个数
push dx
mov ax,table
mov ds,ax
mov ax,[bx]
mov dx,[bx+2] ;取出年份
mov bp,mydata ;年份就是按字符存储的直接显示
mov es,bp
sub ax,3030h
mov es:[si],ax
sub dx,3030h
mov es:[si+2],dx
mov al,20h
mov es:[si+4],al
add si,5
mov ax,[bx+5]
mov dx,[bx+7] ;取出收入
call deal
mov ax,table
mov ds,ax
mov ax,[bx+10] ;取出雇员数
mov dx,0fffh
call deal
mov ax,table
mov ds,ax
mov ax,[bx+13] ;取出人均收入
mov dx,0fffh
call deal
mov ax,21h
mov [si],al
;显示一行子程序
;dx控制显示位置,不能被其他子程序占用
mov ax,mydata
mov ds,ax
mov si,0 ;指定数据位置
pop dx
call show_str ;调用子程序
inc dh ;行加一
add bx,16 ;进入下一行
loop s
;暂停
mov ah,1
int 21h
;退出
mov ax,4c00h
int 21h
comment ;----------------显示子程序------------------------------
功能: 显示子程序
参数:DH 行,dl列 DS:[SI]数据位置
返回:无
;
show_str:
push di
push es
push ax ;保护现场
mov al,160
mul dh ;算出第dh行在显存中的位置
mov di,ax
mov al,2
mul dl ;算出第dl列在第dh行的第几个内存单元
add di,ax ;算出显存的开始单元
mov ax,0b800h
mov es,ax ;初始es
;开始显示
s1:
mov al,[si] ;取出要显示的字符
cmp al,21h ;判断是否是行结束符
je return ;是的话就返回的主程序
cmp al,20h ;判断是否是空格
je space ;是的话就空八个格
add al,30h ;不是空格,开始处理变成对应的ASCII
mov es:[di],al ;放入显存
mov al,2
mov es:[di+1],al ;设置显示属性
add di,2
sc:
inc si
jmp s1
space: ;处理空格
add di,16 ;空八个格
jmp sc
;显示结束
return:
pop ax ;恢复现场
pop es
pop di
ret
comment ;-----------------数据处理子程序----------------------------
功能:处理数据
参数: DX AX
返回:myData段中的一行数据
;调用除法子程序
;判断是否除尽
;没除尽,入栈,循环
;除尽了,放入temp段中 加上标志' '空格20h
;
deal:
;保护现场
push cx
push bx
;开始处理
mov bp,0 ;初始化计数器
cmp dx,0fffh ;判断是多少位的数据,其实这一步有点多余,16位的除法可以用32位的除法子程序处理
jne l
lows: ;16位的被除数处理
mov bx,10
call divw ;调用除法子程序
cmp ax,0 ;判断商是否为零
je lo
push bx ;把余数入栈
inc bp
jmp lows
lo:
push bx
inc bp
jmp same
l: ;32位的被除数处理
mov bx,10
call divdw ;调用除法子程序
cmp dx,0 ;判断商是否为零
je putdata
n0ax:
push cx ;把余数入栈
inc bp
jmp l
putdata:
cmp ax,0 ;判断商是否为零
jne n0ax
push cx
inc bp
;-----------------从栈到mydata-----------------
same:
mov ax,mydata
mov ds,ax
s0:
cmp bp,0
je bk
pop ax ;从栈中取数据
mov [si],al
inc si
dec bp
jmp s0
back:
;处理结束
pop bx
pop cx
;恢复现场
ret
bk:
mov al,20h ;加空格表示一个数结束如:16
mov [si],al
inc si
jmp back
;------------------子程序 16位的除法溢出--------------------------
comment ;
功能:解决16位除法溢出问题
参数:ax被除数,bh除数
返回:AX 商,bl余数
;
divw: ;15位的除法溢出
;保护现场
push dx
;开始运算
mov dl,al ;保存低位
mov al,ah
mov ah,0
div bl ;商在al中,余数在ah中
mov dh,al ;保存高位商
mov al,dl ;在次组成16位
div bl
mov bl,ah ;余数放在bl中
mov ah,dh ;商放在ax中
;运算结束,结果:商在ax中,余数在bl中
pop dx
;恢复现场
ret
;------------------子程序32位的除法溢出--------------------------
comment ;
功能:解决32位除法溢出问题
参数:dx ax被除数,bx除数
返回:DX AX 商,cx余数
;
divdw: ;32位的除法溢出
;保护现场
;开始运算
push ax ;把低位保存起来
mov ax,dx
mov dx,0
div bx ;高八位的商在ax中,余数在dx中
mov cx,ax ;把高位商给cx
pop ax ;低位出栈
div bx ;低位商在ax中,余数在dx中
xchg cx,dx ;dx和cx中的数据交换
;运算结束,结果:商在dx:ax中,余数在cx中
;恢复现场
ret
comment ;-------------设置表格--------------------------
功能:设置表格子程序
参数:无
返回:无
;
settable:
mov ax,data
mov ds,ax
mov bx,0 ;ds:bx->数据
mov si,168 ;ds:si->雇员人数
mov ax,table
mov es,ax
mov di,0 ;es:di->表格
mov cx,21 ;循环21次
s2:
;复制年份
mov ax,[bx]
mov dx,[bx+2]
mov es:[di],ax
mov es:[di+2],dx ;完成复制年份 四个字节
;复制收入
mov ax,[bx+84]
mov dx,[bx+86]
mov es:[di+5],ax
mov es:[di+7],dx ;完成收入的复制
div word ptr[si]
;将人均收入放入指定位置
mov es:[di+13],ax
;复制雇员数
mov ax,[si]
mov es:[di+10],ax ;完成雇员数的复制
add bx,4
add si,2
add di,10h
loop s2
ret
code ends
end start
评论次数(2) |
浏览次数(251) |
类型(汇编作业) |
收藏此文 |