5个字节求和放AX中
注意 字节8位 AX是16位 8位进位,会吞掉AH的内容,所以要在后面加上ADC进位的
MOV AX,0 ;MOV AH,0
CLD ; CF = 0
MOV AL,12H
MOV BL,34H
ADD AL,BL ; AL = AL+BL
ADC AH,0 ;ADD AH + 0 + CF
ADD AL,56H;
ADC AH,0
ADD AL,78H
ADC AH,0
ADD AL,9AH
ADC AH,0
;只要有进位CF=1,AH就加上
; AX = 01AEH
注意加法,8位 结果保存在 AL中 16位保存在AX中?
五个序数求和
1+2+3+4+5 结果放到AL中
简单的
MOV AX,0
MOV AL,1
MOV BL,2
ADD AL,BL ;AL = 1+2
INC BL ;BL = 3
ADD AL,BL ;AL = 3+3
INC BL ;4
ADD AL,BL
INC BL ;5
ADD AL,BL
循环版
MOV AX,0
MOV AL,1
MOV BL,2
MOV CX,4
L1:
ADD AL,BL ;AL = 1+2
INC BL ;BL = 3
LOOP L1
4次循环,因为 在LOOP前,已经加过一次了
内存单元BUF中5个数求和
假设内存单元中
DATA SEGMENT
BUF DB 12H,56H,98H,69H,9BH
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:
LEA BX,BUF
MOV AX,0
MOV AL,[BX]
INC BX ;MOV AL,[BX+1] 56H
ADD AL,[BX]
INC BX ; 98H
ADD AL,[BX];
INC BX ; 69H
ADD AL,[BX];
INC BX ; 9BH
ADD AL,[BX]
CODE ENDS
END START
程序有点问题,思路大概是这样,
判断AL中是否为 奇偶
这里我们用到JZ 和 JNZ 以及 TEST指令 与
注意要分清楚 JNZ 是ZF=0 说明结果不为0
JZ说明 ZF=1 跳转 结果为0
最后一位 D0位 , 1表示奇地址 0表示偶地址,
和1与,如果是1就是奇地址 如果是0就是偶地址
TEST AL,01H
JNZ L1:
....
....
L1:
将AL寄存器中的无符号数乘以10,放AX中
XOR AH,AH ;AH=0 MOV AH,0'
MOV AL,1
SHL AL,1 ;AL = 2AL
MOV BL,AL ;BL = 2AL
SHL AL,1 ;AL = 4AL
SHL AL,1 ;AL = 8AL
ADD AL,BL ;AL = 8AL + 2AL = 10AL
另一种方式
XOR AH,AH ;AH=0 MOV AH,0'
MOV AL,1
ADD AL,AL ;AL = 2AL
ADC AH,0
MOV BX,AX ;BX = 2AX
ADD AX,AX ;
ADD AX,AX ;AX = 8AX
ADD AX,BX ; 10AX
判断AL和BL是否相等
用CMP指令 CMP AL,BL === AL-BL =0 说明相等 也就说明 全0 ZF=1了
MOV AL,5
MOV BL,5
CMP AL,BL
JZ L1 ;AL=BL ZF=1
MOV CX,5
L1:
判断寄存器AL中是否字母'Y’,是AH=0,否则AH=-1
判断字母用CMP指令 例如: a-b 65- 66 借位 测CF=1 JC ? JZ ? JE可以
JZ = 1 说明全0 也就是说 AL的值为Y
MOV AL,'a'
CMP AL,'Y'
JZ L1
MOV AH,-1
JMP L2
L1: MOV AH,0
L2:
; MOV AH,4CH
;INT 21H
判断寄存器AL中是否字母'Y’或'y’(含大小写),是则AH=0,否则AH=-1。
;判断寄存器AL中是否字母'Y’或'y’(含大小写),是则AH=0,否则AH=-1。
MOV AX,0
MOV AL,'b'
CMP AL,'Y'
JZ L1 ;JE
CMP AL,'y'
JZ L1
MOV AH,-1
JMP L2
L1:
MOV AH,0
HLT ;停机 MOV AH,4CH INT 21
L2:
HLT
判断寄存器AL中是正数还是负数,正数AH=0,负数AH=-1
测试指令TEST
JZ 时 ,说明D7时0 是个正数 全0 JZ=1
mov ax,0
MOV AL,123
TEST AL,80H
JZ L1 ; D7 0 js
MOV AH,-1
JMP L2
L1: MOV AH,0
L2:
;END
用JS指令
mov ax,0
MOV AL,123
TEST AL,AL
JS L1 ;JS=1时,说明是负数
MOV AH,0
JMP L2
L1: MOV AH,-1
L2:
;END
用位移指令
mov ax,0
MOV AL,123
SAL AL,1 ;左移一位,D7放进CF中
JNC L1 ;CF = 0 跳转说明,D7位是0 是个正数
MOV AH,-1 ;负数
JMP L2
L1: MOV AH,0
L2:
;END
比较无符号数AX和BX,求较大值存入字变量wmax
;比较无符号数AX和BX,求较大值存入字变量wmax
CMP AX,BX
JAE L1
MOV WMAX,BX
JMP L2
L1: MOV WMAX,AX
L2:
;END
省略版
;比较无符号数AX和BX,求较大值存入字变量wmax
CMP AX,BX
JAE L1
XCHG AX,BX ; MOV AX,BX
L1: MOV WMAX,AX
比较有符号数AX和BX,求较大值存入字变量wmax
有符号用 L小G大
CMP AX,BX
JG L1
XCHG AX,BX ; MOV AX,BX
L1: MOV WMAX,AX
两种写法,标号
CMP AX,BX
JGE L1
MOV WMAX,BX
JMP L2
L1: MOV WMAX,AX
L2: HLT
1+2+3+… +100。结果存入AX
不使用循环版 ,手动循环
XOR AX,AX ;清0,CF= OF = 0
MOV CX,99
MOV AX,1
MOV BX,2
L1: ADD AX,BX
INC BX
DEC CX
JNZ L1 ;CX!=0时,跳转
MOV SUM,AX ;保存结果
LOOP
MOV CX,99
MOV AX,1
MOV BX,2
L1: ADD AX,BX
INC BX
LOOP L1
内存BUF单元开始的10个字节求和,结果存入SUM字节单元
;例2:内存BUF单元开始的10个字节求和,结果存入SUM字节单元
MOV CX,9
LEA BX,BUF
MOV AL,[BX] ;
L1:INC BX
ADD AL,[BX]
LOOP L1
MOV SUM,AL
编写程序段实现:在1000H为首地址的连续10个字节单元中存放了10个有符号数据,找出最大的数,并存入2000H单元:
MOV CX,9
MOV BX,1000H ;LEA BX,[1000H]
MOV AL,[BX]
L2:INC BX;
CMP AL,[BX]
JGE L1 ;比较al是大的,跳转,继续判断
MOV AL,[BX]
L1:
LOOP L2 ;相等于 DEC CX ; JNZ L2
MOV [2000H],AL
考试时。DEC CX 和 JNZ L2 等价 于 LOOP L2
考试 两个空就写DEC。。。。 一个空 写LOOP L2
例1:键盘接收一个字符,判断,若为小写则转换为大写,并屏幕显示;否则退出程序。
利用DOS功能 01H 和 02H
我们在此,要先分清楚
‘0’ - ‘9’ 的 30H - 39H
‘A’ - 'Z' 的 41H - 5AH
'a' - 'z' 的 61H - 7AH
字符是无符号数!!
MOV AH,01H
INT 21H
CMP AL,'a'
JB STOP
CMP AL,'z'
JA STOP
SUB AL,20H
MOV DL,AL
MOV AH,02H
INT 21H
STOP: HLT
屏幕显示字符串'hello.how are you!
;屏幕显示字符串'hello.how are you!
DATA SEGMENT
STRING DB 'HELLO.HOW ARE YOU','$'
DATA ENDS
CODE SEGMENT
ASSUMEE CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
LEA DX,STRING ;把串给DX
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
例1:内存BUF单元开始的2个有符号数字节比较大小,并把大数送MAX单元。
;例1:内存BUF单元开始的2个有符号数字节比较大小,并把大数送MAX单元。
DATA SEGMENT
BUF DB 5,6
MAX DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV AL,BUF
MOV BL,BUF+1
CMP AL,BL ; AL >= BL
JGE L1 ; 说明 AL大 有符号数 L小 G大
MOV MAX,BL
JMP L2 ;这两个交换也可以 XCHG AL,BL
L1:
MOV MAX,AL
L2:
MOV AH,4CH
INT 21H
CODE ENDS
END START
设输入数据为X、输出数据为Y,X和Y均为字节变量,请编制一个完整的源程序计算下面函数值
我们要根据题目 定义 X Y 为字节变量 DB
DATA SEGMENT
X DB 6
Y DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV AL,X ;把x的值给al做比较
CMP AL,0
JG L1 ; 大于0
CMP AL,0
JL L2 ; 小于0
MOV BL,0
JMP L3 ;否则就是=0
L1:
MOV BL,1
JMP L3
L2:
MOV BL,-1
L3:
MOV Y,BL
MOV AH,4CH
INT 21H
CODE ENDS
END START
设置BX的值。判断最高位为1还是0,并显示
;设置BX的值。判断最高位为1还是0,并显示
;正负 有符号数
MOV BX,10
TEST BX,8000H ;不能and 改变值了, 要TEST
JZ L1 ;JS JZ判断是0 JZ=1 说明全0 JNZ判断是不是1
MOV DL,'1'
JMP L2
L1:
MOV DL,'0' ;'0'=30H 要带引号,'0' 说明字符 而02H是输入一个字符 0是数字了
L2:
MOV AH,02H
INT 21H
MOV AH,4CH
INT 21H
另一种
通过 左移 移进CF中 JC说明 最高位时1 跳转
SAL BX,1
JNC L1 ;等于0时 跳L1
MOV .....
L1: ...
无分支方法
MOV DL,0
SHL BX,1
ADC BL,30H
MOV AH,2
INT 21H
移位到CF中 如果是0 ,0+30H
还是30H 如果是1 1+30H = 31H
输出
循环例题
内存buf单元开始存有10个有符号字节数据,求最小值,并存放在min单元。
data segment
buf db 2 ,6,11,-3,19,2,8,-5,7,16
data ends
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
LEA SI,BUF
MOV CX,9
MOV AL,[SI]
L2: INC SI
CMP AL,[SI]
JLE L1
MOV AL,[SI]
L1:
LOOP L2
MOV min,AL
MOV AH,4CH
INT 21H
CODE ENDS
END START
微机原理接口 IN OUT
注意 IN OUT指令 只能用AX ,AL
从20H端口输入一个字节
直接寻址 00H-FFH 0-255 (256)
IN AX,20H
间接寻址 0000H - FFFFH 0-65535 (65536)
MOV DX,20H
IN AX,DX
从内存bvar单元取一个字节送300H端口
内存 ----> CPU ------> 端口
wvar DW 1234H
....
MOV AX,wvar
MOV DX,300H
OUT DX,AX
从3000H读一个字 送入wvar中
MOV DX,300H
IN AX,DX
MOV wvar,AX
查询法 测试端口状态
测试有没有准备好 D0位 有没有检测好,就绪
MOV DX,8000H ;DX指向状态端口
S1:
IN AL,DX ;读状态端口
TEST AL,01H 测试D0位
JZ S1 ;D0=0 表示没有准备好,跳转继续测试
INC DX ;
INC BX ;8000 + 1 = 8001H 也可以 MOV BX,8001H
IN AL,DX