20180411第二次实验总结
实验目的
1.掌握非压缩的BCD码运算及其调整办法
2.掌握Dos功能调用int 21h的1,2,9,10号功能
3.掌握Bios功能调用int 10h的3号功能
1.写一个简单的汇编语言程序,熟悉编译链接调试过程
- 利用masm命令对源文件进行汇编:输入masm命令后连续回车4次,此时汇编生成二进制目标文件hello,obj
- 用link命令对生成的hello.obj进行连接:输入link命令后连续回车4次,连接后才能生成可执行文件hello.exe
- 执行hello.exe文件
[注意⚠️]
1.二进制目标文件obj结尾
2.Dos功能调用。输入一个“Hello world!” 输出一个“hello world!”
首先要把ds:dx数据段赋值为数据的地址
image- ah=10 字符串的输入
- 大写转换为小写add al,20h
- ah=9 字符串的输出
但是如果想要全部都变为小写,则需要使用循环,不然就只能改变第一个的大小写
data segment
buffer db 20,?,21 dup('$')
data ends
code segment
assume cs:code,ds:data
start:
mov ax,seg buffer
mov ds,ax
mov dx,offset buffer
mov ah,10
int 21h
mov buffer[0],0dh
mov buffer[1],0ah
mov ax,seg buffer
mov ds,ax
mov dx,offset buffer
mov ah,9
int 21h
mov ah,4ch
int 21h
code ends
end start
3.bios获取光标调用,将名字输出到光标处,选择自己喜欢的彩色背景,彩色前景
- 把es赋值为b800
- 获取对应的光标位置
- int 10的3号功能为光标位置,会把行号存储在dh,列号存储在dl中,然后显示字符
葭葭葭葭葭葭葭 23:55:11
data segment
data ends
code segment
assume cs:code,ds:data
start:
;把es赋值为b800
mov ax,0b800h
mov es,ax
;获取对应的光标位置(int 10的3号功能为光标位置)
mov bl,0
mov ah,3
mov bh,0
int 10h
;行号存储在dh中,列号存储在dl中
;位置=dh*160+dl*2
mov al,160
;将dh与al, 结果放在ax
mul dh
mov dh,0
shl dl,1
add ax,bx
mov bx,ax
;打出 Ajiajia
mov al,41h
mov es:[bx+0],al
mov byte ptr es:[bx+1],1eh
mov al,6Ah
mov es:[bx+2],al
mov byte ptr es:[bx+3],1eh
mov al,69h
mov es:[bx+4],al
mov byte ptr es:[bx+5],1eh
mov al,61h
mov es:[bx+6],al
mov byte ptr es:[bx+7],1eh
mov al,6Ah
mov es:[bx+8],al
mov byte ptr es:[bx+9],1eh
mov al,69h
mov es:[bx+10],al
mov byte ptr es:[bx+11],1eh
mov al,61h
mov es:[bx+12],al
mov byte ptr es:[bx+13],1eh
code ends
end start
4.实现Y=2X+3,X是一位十进制数。要求X从键盘输入,在下一行上显示“Y=2X+3=”以及十进制计算结果-关键在溢出问题上
1.aam-非压缩BCD码乘法调整
区分举例:十进制数 9和15
- 压缩BCD
- 一个字节表示两位十进制数
- 9F
- 非压缩BCD码
- 一个字节表示一位十进制数
- 09 0F
实现Y=2X+3,X是一位十进制数。要求X从键盘输入,在下一行上显示“Y=2X+3=”以及十进制计算结果
解法一:我最开始的做法,但输出超过两位数就发生了错误
data segment
mess db 'Y=2X+3,Please Input X : $'
show db 'Y=2X+3= $'
data ends
code segment
assume cs:code,ds:data
start:
; 将数据端的段地址赋给ds
mov ax,data
mov ds,ax
;提示信息的显示
mov dx,offset mess
mov ah,9
int 21h
;键盘输入 输入后的值放在al中
mov ah,1
int 21h
sub al,30h ;去掉ASCII码
mov ah,0 ;防止对数据结果造成影响
shl al,1 ;乘2后的结果就放在al中
add al,3 ;加3
mov bl,al ;保存数据
add bl,30h ;加上ASCII码
;显示“Y=2X+3=”,在此之前加入回车换行
mov ah,2
mov dl,0ah
int 21h ;换行
mov dx,offset show
mov ah,9
int 21h
;输出结果
mov ah,2 ;这句话必须有,不然会出现很多奇怪的图片
mov dl,bl
int 21h
mov ah,4ch
int 21h
code ends
end start
实现效果:
image解法二:运用aam,结果是一位数的时候是正常的,但是当结果是两位数的时候,比如输入 4 应该输出 11 ,但结果就开始乱了
实现效果:
image【注意⚠️】输出提示之前自己带上回车和空行
mess2 db 0ah,0dh,'Y=2x+3=$'
知识回顾学习
1.非压缩BCD码的加法-AAA
- 如果AL的低四位大于9,将AL加6,AH加1,AL的高四位清零,CF与AF置1
由于非压缩的BCD码用一个字节表示一个十进制数,调整后若加上30H 就是该数值的ASCII码
image所以AAA的含义为加法执行后可以调整为ASCII
2.非压缩BCD码的减法-AAS
- 如果辅助进位AF为1(AC),将AL减6,AH减1,AL的高四位清零,CF置1
3.非压缩BCD码的乘法-AAM
- 将乘积调整为两个非压缩的BCD码,商(高位)送AH,余数(低位)送入AL
4.非压缩BCD码的除法-AAD
image解法三【正解】:aam+aaa
imagedata segment
mess db 'Y=2X+3,Please Input X : $'
show db 'Y=2X+3= $'
data ends
code segment
assume cs:code,ds:data
start:
;将数据端的段地址赋给ds
mov ax,data
mov ds,ax
;提示信息的显示
mov dx,offset mess
mov ah,9
int 21h
;键盘输入 输入后的值放在al中
mov ah,1
int 21h
sub al,30h ;去掉ASCII码
mov ah,0 ;防止对数据结果造成影响
shl al,1 ;乘2后的结果就放在al中
aam
add ax,3h ;加3
aaa
add ax,3030h ;加上ASCII码
mov bx,ax ;保存数据
;显示“Y=2X+3=”,在此之前加入回车换行
mov ah,2
mov dl,0dh ;回车
int 21h
mov dl,0ah
int 21h ;换行
mov dx,offset show
mov ah,9
int 21h
;输出结果
mov ah,2
mov dl,bh
int 21h
mov dl,bl
int 21h
mov ah,4ch
int 21h
code ends
end start
实现效果如下
image本题总结
1.如果要写十六进制的,就需要带着H。这里的加3,写为 add ax,3h 可行,写为 add ax,3 仍旧可行的原因是 :3和3h在ascii表上表示的是同一个字符,但是 33可和33h不一样了啊
image
网友评论