几个汇编入门小例子

一:打印 Hello World

DATA SEGMENT  
    BUF DB 'HELLO WORLD!  THIS IS MY FIRST ASM FILE! $'  
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 AH,4CH  
    INT 21H  

CODE ENDS  
END START  

小记:

1. 字符串的最后一个字符必须是“$”

2. LEA DX,BUF 等价于 MOV DX,OFFSET BUF

3.通过功能号为 9 的DOS功能调用实现字符串的显示

09H     显示字符串
01H     单个字符的输入
02H     单个字符的输出

二:计算 ffff:0 ~ ffff:b 单元中的数据的和,存储在 dx 中。

分析:

1.运算结果是否会超出dx所能存储的范围?

答:dx ,一个字,有两个字节,16位 ,范围在 0~65535 。ffff:0 ~ ffff:b**内存单元中的数据都是字节型数据**,范围在0~255之间,12个这样的数据相加不会超过65535 ,所以完全可以存放的下!

;实例:计算ffff:0~ffff:b 单元 中的数据的和 ,存储在dx中 。
assume cs:TT 
TT segment 
    start :
    mov ax,0ffffh
    mov ds,ax 

    mov dx,0  

    mov bx,0 

    mov cx,12 
tag:
    mov al,[bx]
    mov ah,0
    add dx,ax 
    inc bx 
    loop tag 

    mov ax,4c00h
    int 21h 

    TT ends  
end 

小记:

1. cx 用来控制 loop 循环次数

2. 字节对应字节 ,字对应字 。

    mov al,[bx]
    mov ah,0
    add dx,ax 

3.汇编中数据必须以0 开头,即 0ffffh ,而不能是 ffffh

三:从键盘输入两个十进制数 ,然后以十进制数的形式输出他们的和 。

分析:

1.键盘输入得到他们的ASCII码值 
2.减去30H,得到以非压缩型BCD数形式表示的十进制数字 
3.相加并进行调整(AAA )
4.再加上30H ,变为对应的ASCII码值 ,输出即可 

DATA SEGMENT  
    INFOR1 DB  "Please input the frist data(<10):$"
    INFOR2 DB  0AH,0DH,"Please input the second data(<10):$" 
    INFOR3 DB  0AH,0DH,"The result is:$ " 
DATA ENDS 

CODE SEGMENT  
    ASSUME CS:CODE ,DS:DATA 
START :
    MOV AX ,DATA
    MOV DS,AX

    MOV DX ,OFFSET INFOR1 ;显示提示信息 
    MOV AH,09H  
    INT 21H 

    MOV AH,01H ;接受输入 
    INT 21H  ;此时等待用户输入,输入的字符一定存放在AL中
    sub AL,30H 

    MOV BL,AL ;转移到 BL 

    MOV DX ,OFFSET INFOR2 ;显示提示信息 
    MOV AH,09H 
    INT 21H

    MOV AH,01H  ;另一个数放在 AL 中
    INT 21H
    sub AL,30H  

    MOV DX ,OFFSET INFOR3
    MOV AH,09H 
    INT 21H 


    XOR AH,AH ; 清零 AH ,CF标志位也会清零 
    add AL,BL  
    AAA  

    push AX 
    MOV  DL,AH 
    add DL,30H
    MOV AH,02H
    INT 21H

    pop AX 
    MOV DL,AL 
    add DL,30H 
    MOV AH,02H
    INT 21H

    MOV AX,4C00H
    INT 21H


    CODE ENDS
END START 

小记:

1. 从键盘输入一个字符 (输入的字符一定存放在AL中

    mov AH,01H ;接受输入 
    int 21H  ;此时等待用户输入,输入的字符一定存放在AL中
    sub AL,30H 

2. XOR XX,XX ; 清零 XX ,CF标志位也会清零

3. 显示一个字符( 显示的一定是 DL中的内容 )

    mov AH,02H
    int 21H

4.因为在途中将有些单词写为小写时出现了错误,所以建议全部写为大些形式 ,保证不会出错 !

5.关于push ax 和 pop ax 。 说实话 ,我还不是很懂,所以不敢乱说 ~_~

6.学习参考链接:(DOS功能调用一览表)https://blog.csdn.net/icurious/article/details/51628343

四:将内存 ffff:0 ~ ffff:b 段元中的数据拷贝到 0:200 ~ 0:20b 单元中 , 0:200 ~ 0:20b 就等价于 0020:0 ~ 0020:b

ASSUME CS:TT 
TT SEGMENT 
START:
    MOV BX,0 

    MOV CX,12
s:  MOV AX,0FFFFH
    MOV DS,AX 
    MOV DL,[BX]

    MOV AX,0020H
    MOV DS,AX 
    MOV [BX],DL 
    INC BX 
    LOOP s

    MOV AX,4C00H
    INT 21H
TT ENDS 
END 

因为每次循环要设置两次ds,效率会比较低下,所以我们来优化一下 :

ASSUME CS:TT 
TT SEGMENT 
START:

    MOV BX,0 
    MOV AX,0020H
    MOV ES,AX

    MOV AX,0FFFFH
    MOV DS,AX 

    MOV CX,12
s: 
    MOV DL,[BX]
    MOV ES:[BX],DL 
    INC BX 
    LOOP s

    MOV AX,4C00H
    INT 21H
TT ENDS 
END 

小记:

1. 因源单元和目标单元相距大于 64KB ,在不同的64KB段里,程序中,每次循环要设置两次ds

2. 使用段前缀 MOV ES:[BX] , DL (其实也很简单了)

3. 0:200h ~ 0:2FFh 共256个字节的空间(几乎不会被使用,什么都不会存放) 可以作为一段安全的空间任意使用

五:将 data 数据段的数据通过栈的性质倒序存入

ASSUME CS:TT,DS:DATA,SS:STACK  

DATA SEGMENT  
    DW 0123H,0456H,0789H,0ABCH,0DEFH,0FEDH,0CBAH,0987H ;数据段原始数据
DATA ENDS 

STACK SEGMENT
    DW 0,0,0,0,0,0,0,0 
STACK ENDS 

TT SEGMENT 
START:       ; CS:IP pointer here 
    MOV AX,STACK 
    MOV SS,AX 
    MOV SP,16 ;栈顶指针指向 16(2*8) 

    MOV AX,DATA
    MOV DS,AX 

    MOV BX,0
    MOV CX,8 
tag:PUSH [BX]
    ADD  BX,2
    LOOP tag 

    MOV BX,0
    MOV CX,8
s:  POP [BX]
    ADD BX,2
    LOOP s

    MOV AX,4C00H
    INT 21H
    TT ENDS 
END START 

小记:

1.

 dw 即 define word  , 定义字型数据 
 db 即 define byte  , 定义字节型数据 

2. DS,CS,SS,ES 不能直接给数据,必须通过通用寄存器(ax,bx,cx,dx )给他们赋值

比如: MOV DS,DATA     会出错

3. sp 一次移动两个单元(即一个字)

4.

    push指令 –> ①SP-2 –> ②将**字型数据**存放到SS:SP地址中 
    pop指令 –> ①将SS:SP地址的**字型**数据取出来 –> ②SP+2 

六:输入年龄(如果是三位数就直接输入即可,如果是两位数,第三位数写为0 。比如:032 ),输出其所对应的年龄段名称 。

分析:

1.得到三个数字字符
2.先判断百位是不是 1,如果是1 ,在判断十位大不大于5 ,
  大于5,其他物种,小于5,是个老人啊 
3.再判断百位是不是0 ,如果不是,其他物种,如果是,判断十位
    < 60 child  
    60~80 middle man 
    > 80 old man 

DATA    SEGMENT
        INFOR1  DB 0AH,0DH,"Please  input your age :$"
        INFOR2  DB 0AH,0DH,"Your age is < 60 ,I think you are a child $"
        INFOR3  DB 0AH,0DH,"You are a middle man $"
        INFOR4  DB 0AH,0DH,"You are  a  old man $"
        INFOR5  DB 0AH,0DH,"You are a  other species !$" 
        AGE     DB 0,0,0
DATA    ENDS

CODE    SEGMENT
      ASSUME CS:CODE,DS:DATA
START:  
        MOV  AX,DATA
        MOV  DS,AX

        MOV  DX,OFFSET INFOR1
        MOV  AH,09H
        INT 21H 

        MOV CX,3 
        MOV BX,OFFSET AGE 
    tag:
        MOV AH,01H  ;接受输入 
        INT 21H    ;此时等待用户输入,输入的 one ge 字符一定存放在 AL 中
        MOV [BX],AL  
        INC BX 
        LOOP tag 

        MOV BX,OFFSET AGE    
        CMP  [BX],BYTE PTR '1'
        JE   TEMP   ; == 1

        CMP BYTE PTR [BX],'0'
        JNE  OTHER  ; != 0 

        INC BX 
        CMP  [BX],BYTE PTR '6'
        JB CHILD 

        CMP  [BX],BYTE PTR'8'
        JB MAN 
        JNB OLD_MAN  

        JMP  PEND
    TEMP:
        INC BX
        CMP [BX],BYTE PTR'5'
        JNA OLD_MAN ; <= 5 
        JA OTHER   ; >5
    CHILD:
        MOV  DX,OFFSET INFOR2
        MOV  AH,09H
        INT 21H 
        JMP  PEND       ;注意执行完一个分支后应使程序跳出
    MAN:    
        MOV  DX,OFFSET INFOR3
        MOV  AH,09H
        INT 21H 
        JMP  PEND       

    OLD_MAN:    
        MOV  DX,OFFSET INFOR4 
        MOV  AH,09H
        INT 21H 
        JMP  PEND       

    OTHER:  
        MOV  DX,OFFSET INFOR5 
        MOV  AH,09H
        INT 21H 
        JMP  PEND       

    PEND:
        MOV  AH,4CH
        INT  21H
CODE    ENDS
END  START

这里写图片描述

小记:

1.字与字节必须对应

    CMP  [BX],BYTE PTR '1'
    JE   TEMP   ; == 1

2. 检测比较结果的条件转移指令( je 和 jz相同)

je/jz     等于则转移         zf=1

jne/jnz    不等于则转移     zf=0

jb     低于则转移        cf=1

jnb    不低于则转移    cf=0

ja     高于则转移        cf=0且zf=0

jna    不高于则转移    cf=1或zf=1

助记:

    e : equal

    ne : not equal

    b: below ;在下面,到下面,低于;(表示位置)在…下面 

    nb : not below

    a : above ;表示程度)超过;(表示等级)在…之上;(表示位置)在…正上

    na : not above
posted @ 2018-05-16 15:23  Tattoo_Welkin  阅读(363)  评论(0编辑  收藏  举报