提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、第一个程序
1.汇编程序从写出到执行的过程,加载后,CPU的 CS:IP指向程序的第一条指令(即程序的入口)
2.程序执行过程跟踪
DOS系统中,EXE文件中的程序的加载过程
二、[BX]和loop指令
1.[bx]的含义:[bx]同样表示一个内存单元,它的偏移地址在bx中,段地址默认在ds中。
2.loop指令的格式是:loop标号,CPU执行loop指令的时候,要进行两步操作。
- cx=cx-1
- 判断cx中的值,不为零的则转至标号处执行程序,如果为零则向下执行
3.段前缀 这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的“ds:”,“cs:”,“ss:”,“es:”,在汇编语言中称为段前缀。
- mov ax, ds:[bx]
- mov ax, cs:[bx]
- mov ax, ss:[bx]
- mov ax, es:[bx]
- mov ax, ss:[0]
- mov ax, cs:[0]
三、包含多个段的程序
- 数据段:存放数据的段。使用时候,用DS寄存器。
- 程序段:用来存放程序的段。使用的时候,用CS和IP寄存器。
- 栈段:是一个栈。使用时,初始设置SS和SP寄存器。
在代码段中使用数据
计算 8 个数据的和存到 ax 寄存器
assume cs:codecode segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ;define word 定义8个字形数据
start: mov bx, 0 ;标号start
mov ax, 0
mov cx, 8
s: add ax, cs:[bx]
add bx, 2
loop s
mov ax, 4c00h
int 21h
code ends
end start ;end除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方
;用end指令指明了程序的入口在标号start处,也就是说,“mov bx,0”是程序的第一条指令。
在代码段中使用栈
利用栈,将程序中定义的数据逆序存放。
assume cs:codesgcodesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ; 0-15单元
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 16-47单元作为栈使用
start: mov ax, cs
mov ss, ax
mov sp, 30h ;将设置栈顶ss:sp指向栈底cs:30。 30h = 48d
mov bx, 0
mov cx, 8
s: push cs:[bx]
add bx, 2
loop s ;以上将代码段0~15单元中的8个字型数据依次入栈
mov bx, 0
mov cx, 8
s0: pop cs:[bx]
add bx,2
loop s0 ;以上依次出栈8个字型数据到代码段0~15单元中
mov ax,4c00h
int 21h
codesg ends
end start ;指明程序的入口在start处
将数据,代码,栈放入不同的段中
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ;0-15单元
data endsstack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;0-31单元
stack endscode segment
start: mov ax, stack;将名称为“stack”的段的段地址送入ax
mov ss, ax
mov sp, 20h ;设置栈顶ss:sp指向stack:20。 20h = 32d
mov ax, data ;将名称为“data”的段的段地址送入ax
mov ds, ax ;ds指向data段
mov bx, 0 ;ds:bx指向data段中的第一个单元
mov cx, 8
s: push [bx]
add bx, 2
loop s ;以上将data段中的0~15单元中的8个字型数据依次入栈
mov bx, 0
mov cx, 8
s0: pop [bx]
add bx, 2
loop s0 ;以上依次出栈8个字型数据到data段的0~15单元中
mov ax, 4c00h
int 21h
code ends
end start
;“end start”说明了程序的入口,这个入口将被写入可执行文件的描述信息,
;可执行文件中的程序被加载入内存后,CPU的CS:IP被设置指向这个入口,从而开始执行程序中的第一条指令
四、更灵活的定位内存地址和方法
1.and和or
and指令:逻辑与指令,按位进行与运算。
mov a1 ,01100011B
and a1 , 00111011B
执行后:a1=00100011B 即都为1才为1。
or指令:逻辑或指令,按位进行或者运算。
mov a1 ,01100011B
or a1 ,00111011B
执行后:a1=01111011B即只有一个为1的就为1。
2.关于ASCII码
世界上有很多地编码方案,有一种方案叫做ASCII编码,是在计算机系统中通常被采用的。简单的说,所谓的编码方案,就是一套规则,它约定了什么信息对应什么对象。比如说,在ASCII编码中,用61H表示"a"。
关于大小写转换问题:
小写字母的ASCII码的值比大写字母ASCII码的值大20H
小写字母的第五位为1,大写字母的第五位为0。其他的一致。
3.[bx+idata]
[bx+idata]表示一个内存单元,例如:mov ax,[bx+200]
该指令也可以改写成如下格式:
- mov ax, [200+bx]
- mov ax, 200[bx]
- mov ax, [bx].200
4.SI,DI与寻址方式的灵活应用
1.SI,DI
- si和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位的寄存器使用。
- [bx+si]和[bx+di]的含义相似。[bx+si]表示一个内存单元,它的偏移地址为(bx+si),相当于指令mov ax ,[bx+si]的含义,将一个内存单元的字数据的内容送入ax,段地址在ds中。
- [bx+si+data]和[bx+di+data]的含义相似,表示它的偏移地址为(bx+si+data)。
五、数据处理的两个基本问题
1.bx ,si ,di ,和bp
在8086CPU中,只有这四个寄存器可以用在“[......]”中来进行内存单元的寻址。在[ ]中,这四个寄存器可以单个出现,或者只能以这四种组合出现:bx和si,bx和di,bp和si,bp和di。
只有在“[......]”中使用寄存器bp,而指令中没有显性的给出段地址,段地址默认在ss中。
2.指令要处理的数据有多长
8086CPU的指令,可以处理两种尺寸的数据,byte和word。通过寄存器名指明要处理的数据的尺寸。例如: mov al, ds:[0] 寄存器al指明了数据为1字节
在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度,X在汇编指令中可以为word或byte。例如:mov byte ptr ds:[0], 1 byte ptr 指明了指令访问的内存单元是一个字节单元
有些指令默认了访问的是字单元还是字节单元。例如,push [1000H],push 指令只进行字操作。
3.div指令,dd,dup,mul指令
div是除法指令
1.除数:有8位和16位两种吗,在一个寄存器或者内存单元中。
2.被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
3.结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。
伪指令dd
db和dw定义字节型数据和字型数据。
dd是用来定义dword双字型数据的伪指令。
操作符dup
dup在汇编语言中同db,dw,dd等一样,也是由编译器识别处理的符号。它和db,dw,dd等数据定义的伪指令配合使用,用来进行数据的重复。
- db 3 dup (0) ;定义了3个字节,它们的值都是0,相当于db 0,0,0。
- db 3 dup (0, 1, 2) ;定义了9个字节,它们是0、1、2、0、1、2、0、1、2,相当于db 0,1,2,0,1,2,0,1,2。
- db 3 dup ('abc', 'ABC') ;定义了18个字节,它们是abcABCabcABCabcABCC,相当于db 'abc', 'ABC' ,'abc' , 'ABC, 'abc', 'ABC'。
mul指令是乘法指令,使用mul指令做乘法的时候:相乘的两个数:要么都是8位,要么都是16位。