汇编程序设计 练习

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

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值