微机原理(汇编语言)学习

编程题A-1:在数组字变量ARRAY中有10个数,将数组中这10个数求和,放到RESULT存储区中。

DATA SEGMENT
    ARRAY DW 1H,1H,1H,1H,1H,1H,1H,1H,1H,1H  ;存10个字在ARRAY中
    COUNT EQU ($-ARRAY)/2	;获得ARRAY中元素个数
    RESULT DW ?	;存最终结果
DATA ENDS
CODE SEGMENT
    ASSUME CS:CODE,DS,DATA
START:
    MOV AX,DATA
    MOV DS,AX
    MOV AX,0	;用来临时存储求和结果
    MOV CX,COUNT	;循环条件
    LEA BX,[ARRAY]	;将ARRAY首地址存BX
LOP:ADD AX,[BX]	;求和
    ADD BX,2	;跳过一个字
    LOOP LOP	;CX!=0继续循环 CX=CX-1
    MOV RESULT,AX	;存最终结果
    MOV AH,4CH	;DOS功能调用结束程序
    INT 21H
CODE ENDS
    END START

注:DX可能有其他用途,会一直变化,不太清楚


编程题A-2:已知有多个元素(不少于10个)存放在以BUF为首址的字节存储区中,试找出其中第一个负数放到BUFF字节存储区。

DATA SEGMENT
    BUF DB 5,6,2,6,-6,3,1,5,2,-2 ;初始化数据
    COUNT EQU $-BUF	;获取数据个数
    BUFF DB 0	;存最终结果
DATA ENDS
CODE SEGMENT
    ASSUME CS:CODE,DS:DATA
START:
    MOV AX,DATA
    MOV DS,AX
    MOV AX,0	;存当前要判断的数
    LEA BX,[BUF]   ;存首地址
    MOV CX,COUNT 	;循环条件
LOP:   
    MOV AL,[BX]
    CMP AL,0
    JL  NEXT	;小于就跳转储存结束
    INC BX
    LOOP LOP

NEXT:
    MOV BUFF,AL
    MOV AH,4CH
    INT 21H

CODE ENDS
    END START

注意:1.数据都是字节类型,所以要用AL第八位来存
2.比较大于小于0要用有符号数比较


编程题A-3:设有三个字节变量X、Y、Z,试找出X、Y有符号数中较大者送入Z中,编写程序。

DATA SEGMENT
    X   DB  5H
    Y   DB  0AH
    Z   DB  4H
DATA ENDS
CODE SEGMENT
    ASSUME  CS:CODE,DS:DATA
START:
    MOV AX,DATA
    MOV DS,AX
    MOV AL,X
    MOV BL,Y
    MOV CL,Z
    CMP AL,BL ;X和Y比较
    JG  FIRST	;X大跳转
    CMP BL,CL	;X小,Y和Z比较
    JG  SECOND	;Y大跳转,如果Y小 Z最大
    MOV AH,4CH
    INT 21H

FIRST:
    CMP AL,CL	;X和Z比较
    JG  THIRD	;X大跳转
    MOV AH,4CH
    INT 21H

SECOND:
    MOV Z,BL ;将最大的Y存在Z里
    MOV AH,4CH
    INT 21H

THIRD:
    MOV Z,AL	;将最大的X存在Z里
    MOV AH,4CH
    INT 21H
    
CODE ENDS
    END START

注:1. CMP不能用变量进行比较
2. 变量间不能直接 MOV


编程题A-4:设在变量单元A、B和C中存放有三个数,若三个数都不为0,则求出三个数之和存入D中;若有一个为0,则将其他两个单元也清零,编写程序。

DATA   SEGMENT
    A   DB  5H
    B   DB  5H
    C   DB  0AH
    D   DB  0
DATA    ENDS
CODE   SEGMENT
    ASSUME  CS:CODE,DS:DATA
START:
	;思路:分别将A,B,C中的数存到AL中,然后和0比较,如果是0就跳转清零,	
	;如果不是0就加到BL中,最后将BL结果中的数存到变量D中,DOS命令结束
    MOV AX,DATA
    MOV DS,AX
    MOV AL,A
    MOV BL,0
    CMP AL,0
    JZ  ZERO
    ADC BL,AL
    MOV AL,B
    CMP AL,0
    JZ  ZERO
    ADC BL,AL
    MOV AL,C
    JZ  ZERO
    ADC BL,AL
    MOV D,BL
    MOV AH,4CH
    INT 21H
     
ZERO:
    MOV A,AL
    MOV B,AL
    MOV C,AL
    MOV AH,4CH
    INT 21H

CODE    ENDS
    END START

注:MOV 可以将存储器中的数移到变量里,不能变量直接移动。


编程题B-1:已知以BUF为首址的字存储区中存放着多个有符号的二进制数,试编写程序,将正数送以BUF1为首址的字存储区中,将负数数送以BUF2为首址的字存储区中。

DATA    SEGMENT
    BUF DW  0A235H,0AH,31H,0A263H,22H,51H,0CAH,8211H,0E3H,3H
    COUNT   EQU ($-BUF)/2
    BUF1    DW  10  DUP(0)
    BUF2    DW  10  DUP(0)
DATA    ENDS
CODE    SEGMENT
    ASSUME  CS:CODE,DS,DATA
START:
	;思路通过遍历BUF中的每个数,如果大于等于0就存到BUF1中,如果小于0就存到BUF2中
    MOV AX,DATA
    MOV DS,AX
    MOV CX,COUNT
    LEA SI,BUF1
    LEA DI,BUF2
    LEA BX,BUF
LOP:    
    MOV AX,[BX]
    ADD BX,2
    CMP AX,0
    JGE X
    MOV [DI],AX
    ADD DI,2
    LOOP LOP
    MOV AH,4CH
    INT 21H
X:  
    MOV [SI],AX
    ADD SI,2
    LOOP LOP
    MOV AH,4CH
    INT 21H
CODE    ENDS
    END START

注1. 这里需要用到串指令,利用SI和DI可以获取串地址,并且利用MOV来向串里存数
2.需要利用DUP先开辟一块内存空间用来存数


编写程序,将一个包含20个元素的数组STRING分成一个偶数数组STRING1和一个奇数数组STRING2。

DATA    SEGMENT
    STRING  DB  2,6,12,6,4,2,7,4,8,2,6,8,45,8,2,4,2,3,6,5
    COUNT   EQU $-STRING
    STRING1 DB  20  DUP(0)
    STRING2 DB  20  DUP(0)
DATA    ENDS
CODE    SEGMENT
    ASSUME  CS:CODE,DS,DATA
START: 
	;思路:循环变量STRING数组,如果是偶数存在S1里,如果是奇数存在S2里
    MOV AX,DATA
    MOV DS,AX
    MOV CX,COUNT
    LEA BX,STRING
    LEA SI,STRING1
    LEA DI,STRING2
LOP:
    MOV AL,[BX]
    SHR AL,1
    JC  JI
    MOV AL,[BX]
    MOV [SI],AL
    INC SI
    INC BX
    LOOP LOP
    MOV AH,4CH
    INT 21H

JI:         
    MOV AL,[BX]
    MOV [DI],AL
    INC DI
    INC BX
    LOOP LOP
    MOV AH,4CH
    INT 21H

CODE    ENDS
    END START

将AL右移然后判断后不能直接将AL存到数组里,因为值变化了,所以需要将STRING里面的数重新赋值给AL后再存到数组里


编程题B-3:在以BUF为首址的字节单元中存放了COUNT个有符号数,编写程序找出其中最大数送MAX单元,最小数放入MIN单元。

DATA    SEGMENT
    BUF DB  5,2,6,4,2,1,5,-3,-5
    COUNT   EQU $-BUF                       
    MAX DB  0          
    MIN DB  0
DATA    ENDS
CODE    SEGMENT
    ASSUME  CS:CODE,DS,DATA     
START:
    MOV AX,DATA
    MOV DS,AX
    LEA BX,BUF
    MOV CX,COUNT-1
    MOV AL,[BX]
    MOV MIN,AL
    MOV MAX,AL
    INC BX
LOP:
    MOV AL,[BX]
    CMP MIN,AL
    JG  X
    CMP MAX,AH
    JL  Y
Z:  INC BX
    LOOP LOP
NEXT:
    MOV AH,4CH
    INT 21H    
    
X:  
    MOV AL,[BX]
    MOV MIN,AL
    JMP Z

Y:
    MOV AH,[BX]
    MOV MAX,AH
    JMP Z
    

CODE    ENDS
    END START

注意:有符号数比较大小,如果是十六进制,数值大不一定大,因为他可能是负数。


编程题C-1:已知在以BUF为首地址的字节存储区中,存放着一个以′$′作结束标志的字符串,试编写程序,将其中的大写字母转换成小写字母存放在新字符串NEWBUF,并将原字符串与新字符串都在屏幕上显示出来 。

DATA    SEGMENT
    BUF DB  'HeLlO,WoRlD!$'
    COUNT EQU   $-BUF
    NEWBUF  DB  20  DUP(0)
DATA    ENDS
CODE    SEGMENT
    ASSUME  CS:CODE,DS:DATA
 ;思路:通过遍历字符串,碰到大写就转换为小写,存到新串,涉及到串操作,最后利用09号DOS命令配合DX输出字符串
START:
    MOV AX,DATA
    MOV DS,AX
    LEA BX,[BUF]
    MOV CX,COUNT
    LEA DI,[NEWBUF]
LOP:    
    MOV AL,[BX]
    CMP AL,41H
    JAE X
    MOV [DI],AL
    INC DI
    INC BX
    LOOP LOP
    LEA DX,BUF
    MOV AH,09H
    INT 21H
    
    MOV AH,02H
	MOV DL,0DH
	INT 21H
	
	MOV AH,02H
	MOV DL,0AH
	INT 21H
	
    LEA DX,NEWBUF
    MOV AH,09H
    INT 21H
    
    MOV AH,4CH
    INT 21H
    
X:  
    CMP AL,5AH
    JBE Y
    MOV [DI],AL
    INC DI
    INC BX
    LOOP LOP

Y:  
    ADD AL,20H
    MOV [DI],AL
    INC DI
    INC BX
    LOOP LOP
        

CODE    ENDS
    END START

注意:1.想回车用02号DOS命令既要输出回车,也要输出换行
2.09号DOS命令输出字符串,要将字符串先保存在DX中
3.字符串需要以$结尾


编程题C-2:已知在以BUF为首地址的字节存储区中存放一个有NUMBER长度的字符串,试编写程序,将其中非字母字符用空格代替,存放到新字符串STR中,并将原字符串与新字符串都在屏幕上显示出来 。

DATA    SEGMENT
    BUF DB  'Hello,World!$'
    NUMBER  EQU $-BUF
    STR DB    DUP(0)
DATA    ENDS
CODE    SEGMENT
    ASSUME  CS:CODE,DS:DATA
START:
    MOV AX,DATA
    MOV DS,AX
    LEA DI,STR
    LEA BX,BUF
    MOV CX,NUMBER-1
LOP:    
    MOV AL,[BX]
    CMP AL,41H
    JB  NEXT
    CMP AL,7AH
    JA  NEXT
    CMP AL,5AH
    JBE NEXT2
    CMP AL,61H
    JAE NEXT2
NEXT:
    MOV [DI],20H
    INC DI
    INC BX
    LOOP LOP
    MOV AL,'$'
    MOV [DI],AL
    LEA DX,BUF
    MOV AH,09H
    INT 21H
    
    MOV AH,02H
	MOV DL,0DH
	INT 21H
	
	MOV AH,02H
	MOV DL,0AH
	INT 21H
	
    LEA DX,STR
    MOV AH,09H
    INT 21H
    
    MOV AH,4CH
    INT 21H


NEXT2:
    MOV [DI],AL
    INC DI
    INC BX
    LOOP LOP

CODE    ENDS
    END START

注:1.字符串复制最后要查看STR结尾有没有$,没有将打印不出来


编程题C-3:已知在以BUF为首地址的字节存储区中存放着一个长度为15的字符串,编写程序,将字符串显示出来,并测试字符串中是否有数字符号,若有,则在屏幕上显示“yes”,否则显示“no”。

DATA SEGMENT
    BUF DB 'Hello,World!JXY$'
    COUNT EQU $-BUF
    STR1 DB 'yes$'
    STR2 DB 'no$'
DATA ENDS
CODE    SEGMENT
    ASSUME  CS:CODE,DS:DATA
START:
    MOV AX,DATA
    MOV DS,AX
    LEA DX,BUF
    MOV AH,09H
    INT 21H
    
    MOV DL,0AH
    MOV AH,02H
    INT 21H
    MOV DL,0DH
    MOV AH,02H
    INT 21H
    LEA BX,BUF
    MOV CX,COUNT
    MOV AH,0
LOP:
    MOV AL,[BX]
    INC BX
    CMP AL,30H
    JB  X
    CMP AL,39H
    JA  X
    MOV AH,1
NEXT:
    AND AH,1
    JZ  Y
    LEA DX,STR1
    MOV AH,09H
    INT 21H
    
    MOV AH,4CH
    INT 21H

Y:  
    LEA DX,STR2
    MOV AH,09H
    INT 21H
   
    
    MOV AH,4CH
    INT 21H
X:  
    LOOP LOP
    JMP NEXT
   
    

CODE    ENDS
    END START

注:1. MOV AX,DATA MOV DS,AX 没写会乱码
2. 字符串变量结尾要加$

你可能感兴趣的:(汇编语言,学习,算法)