汇编语言零基础(一)

汇编语言零基础(一)

1. 基础知识:

1.1 机器语言:

机器语言是机器指令的集合。

1.2 汇编语言:

汇编语言的主体是汇编指令。
汇编指令是机器指令便于记忆的书写形式。

1.3 寄存器:

CPU中可以存储数据的器件。

1.4 汇编语言的组成:

1.汇编指令
2.伪指令
3.其他符号

1.5 存储器:

要让CPU工作,就必须提供指令和数据。
指令和数据在存储器中存放。
在内存或磁盘中,指令和数据没有任何区别,都是二进制数据。

1.6 存储单元:

存储器被划分为若干个存储单元,从0开始顺序编号。

1.7 CPU对存储器的读写:

CPU读写必须进行三种信息的交互:
1.地址信息;
2.控制信息;
3.数据信息。
在计算机中有专门连接CPU和其他芯片的导线,通常称为总线。总线逻辑上分为:
1.地址总线;
2.数据总线;
3.控制总线。

1.8 地址总线:

CPU是通过地址总线来指定存储单元的。

1.9 数据总线:

CPU与其他部件之间的数据传输是通过数据总线完成的。
数据总线的宽度决定了CPU和外界的数据传送速度。

1.10 控制总线:

控制总线的宽度决定了CPU对外部组件的控制能力。
有一根读信号输出控制线负责由CPU向外传送读信号,CPU向该控制线上输出低电平表示将要读取数据。
有一根写信号输出控制线负责由CPU向外传送写信号。

1.11 内存地址空间:

1.12 主板:

主板上有一些核心器件,这些器件通过总线相连。

1.13 接口卡:

1.14 各类存储器芯片:

2. 寄存器(CPU工作原理):

一个典型CPU由运算器,控制器,寄存器等器件组成,这些器件靠内部总线相连。
内部总线实现CPU内部各个器件之间的联系;
外部总线实现CPU和主板上其他器件的联系。

2.1 通用寄存器:

AX,BX,CX,DX通常用来存放一般性数据,被称为通用寄存器。
为了保证兼容性,AX可以分为两个8位寄存器来使用:AH和AL,其他寄存器同理。

2.2 字在寄存器中的存储:

一个字可以存在一个16位寄存器中,这个字的高位和低位自然就存在这个寄存器的高8位寄存器和低8位寄存器中。

2.3 常用汇编指令:

汇编指令不区分大小写。

mov ax,18    ax = 18;
add ax,8     ax = ax + 8;
mov ax,bx    ax = bx;
add ax,bx    ax = ax + bx;

2.4 物理地址:

所有的内存单元构成的存储空间是一个一维的线性空间。
这个唯一的地址称为物理地址。

2.5 16位结构的CPU:

16位结构的CPU有以下特征:
1.运算器一次最多处理16位的数据;
2.寄存器的最大宽度为16位;
3.寄存器和运算器之间的通路是16位的。

2.6 CPU给出物理地址的方法:

8086地址总线有20位,寻址能力为1M。
8086内部为16位结构,只能传送16位地址,表现出的寻址能力只有64K。

8086采取的方法:在内部用2个16位地址合成为一个20位地址:
16位段地址+16位偏移地址=20位物理地址。

地址加法器工作原理:
物理地址 = 段地址*16 + 偏移地址

2.7 段的概念:

CPU可以用不同的段地址和偏移地址形成同一个物理地址。

2.8 段寄存器:

段寄存器就是提供段地址的。
8086CPU有4个段寄存器:CS,DS,SS,ES。

2.9 CS和IP:

CS为代码段寄存器,IP为指令指针寄存器。
在任何时候,CPU将CS,IP中的内容当做指令的段地址和偏移地址,用他们合成指令的物理地址,到内存中读取指令码,执行。
如果说内存中的一段信息曾被CPU执行过的话,那么它所在的内存单元必然被CS:IP指向过。

2.10 8086PC互作过程的主要描述:

1.从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
2.IP=IP+所读取指令的长度,从而指向下一条指令;
3.执行指令。回到步骤1。

2.11 修改CS、IP的指令:

在CPU中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对CPU的控制。

8086CPU为CS、IP提供了另外的指令来改变他们的值:转移指令。

同时修改CS和IP的值:用指令中给出的段地址修改CS,偏移地址修改IP。
jmp 段地址:偏移地址

jmp 2AE3:3
jmp 3:0B46

只修改IP的内容:用寄存器中的值修改IP。
jmp 某一合法寄存器

mov ax,200
jmp ax

2.12 代码段:

对于8086PC机,在编程时可以将一组内存单元定义为一个段。
CPU只认被CS:IP指向的内存单元中的内容为指令。所以要将CS:IP指向所定义的代码段中的第一条指令的首地址。

3. 寄存器(内存访问):

3.1 内存中字的存储:

任何两个地址连续的内存单元,可以将他们看成两个内存单元,也可以看成一个字单元中的高位字节单元和低位字节单元。

3.2 DS和[address]:

CPU要读取一个内存单元的时候,必须给出这个内存单元的地址。
8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址。

8086CPU不支持将数据直接送入段寄存器的操作,DS是一个段寄存器。
mov ds,1000H 是非法的。

[address]表示一个偏移地址为address的内存单元。

3.3 字的传送:

8086是16位结构,可以一次性传送16位的数据,也就是一个字。

3.4 mov、add、sub指令:

mov:

mov 寄存器 数据
mov 寄存器 寄存器
mov 寄存器 内存单元
mov 内存单元 寄存器
mov 段寄存器 寄存器
mov 寄存器 段寄存器

add和sub不能操作段寄存器的值。

3.5 数据段:

定义用来专门存储数据的连续内存空间。

3.6 栈:

8086的入栈和出栈都是以字为单位操作的。

push ax
pop ax

8086CPU中有两个寄存器:
段寄存器SS:存放栈顶的段地址
寄存器SP:存放栈顶的偏移地址

任意时刻SS:SP指向栈顶元素。

push ax操作过程:
1.SP=SP-2;
2.将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。

pop ax操作过程:
1.将SS:SP指向的内存单元处的数据送入ax中;
2.SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。

3.7 CPU提供的栈机制:

3.8 栈顶超界的问题:

8086不保证对栈的操作不会超界。

3.9 push、pop指令:

push和pop还可以对段寄存器进行操作。

3.10 栈段:

一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么都不是。关键在于CPU中寄存器的设置。

4. 第一个程序:

4.1 源程序从写出到执行的过程:

1.编写;
2.编译:使用汇编语言编译程序(MASM.EXE)对源程序文件中的源程序进行编译,产生目标文件;
3.链接:再用链接程序(LINK.EXE)对目标文件进行链接,生成可在操作系统中直接运行的可执行文件。
4.执行:操作系统依照可执行文件中的描述信息,将可执行文件中的机器码和数据加载进内存,并进行相关的初始化,然后由CPU执行程序。

可执行文件中包含两部分内容:
程序和数据;
相关的描述信息。

4.2 源程序:

4.2.1 基本语法:

伪指令:没有对应的机器码的指令,最终不被CPU所执行。
伪指令由编译器来执行。

定义一个段:

段名 segment
......
段名 ends

end是一个汇编程序结束的标志:

......
......
end

assume:

assume cs:codesg
codesg segment
......
code ends
end

4.2.2 DOS中的程序运行:

DOS是一个单任务操作系统。
想要运行程序P2,必须有一个正在运行的程序P1,将P2从可执行文件加载入内存后,将CPU的控制权交给P2,P2才得以执行。P2开始运行后,P1暂停运行。P2运行完毕后,将CPU控制权还给P1,此后,P1继续运行。

程序返回:在程序末尾添加:

mov ax,4c00H
int 21H

4.3 编辑源程序:

4.4 编译:

masm 1.asm

生成obj文件,内部为机器码。

4.5 链接:

link 1.asm

链接的作用:
1.当源程序很大时,可以将它分为多个源程序文件进行编译,每个源程序编译成为目标文件后,再用链接程序将它们链接在一起,生成一个可执行文件;
2.程序中调用了某个库文件中的子函数,需要将这个库文件和该程序生成的目标文件链接在一起,生成一个可执行文件;
3.一个源程序编译后,得到了存有机器码的目标文件,目标文件中有的内容还不能直接用来生成可执行文件,链接程序将这些内容处理成最终的可执行信息。

4.6 以简化的方式进行编译和链接:

省略确认过程:

masm 1.asm;
link 1.asm;

更简化的方式:

ml 1.asm

4.7 可执行文件中的程序装入内存并运行的原理:

DOS中有一个程序command.com,这个程序在DOS中称为命令解释器,也就是DOS系统的shell。

exe的执行过程:
1.在DOS中执行exe时,是正在运行的command将exe中的程序加载入内存;
2.command设置CPU的CS:IP指向程序的第一条指令,从而使程序得以运行;
3.程序运行结束后,返回到command中,CPU继续运行command。

4.8 exe文件的加载过程总结:

1.程序加载后,ds中存放着程序所在内存区的段地址,这个内存区的偏移地址为0,则程序所在的内存区的内存区的地址为ds:0;
2.这个内存区的前256个字节存放PSP,是DOS用来和程序进行通信的;
3.从256字节向后的空间存放的是程序。

5. [BX]和loop指令:

5.1 [bx]:

5.1.1 含义:

[0]表示内存单元,它的偏移地址是0。
[bx]同样也表示一个内存单元,它的偏移地址在bx中。

5.1.2 描述性符号():

1.ax中的内容为0010H,我们可以这样来描述:(ax) = 0010H;
2.2000:1000中的内容为0010H,可以描述为:(21000H) = 0010H;
3.对于mov ax, [2]的功能,可以描述为:(ax) = ((ds)*16+2);
4.对于mov [2], ax的功能,可以描述为:((ds)*16+2) = (ax);
5.对于add ax, 2的功能,可以描述为:(ax) = (ax) + 2;
6.对于push ax的功能,可以描述为:(sp) = (sp) - 2,((ss)*16+(sp)) = (ax);
7.对于pop ax的功能,可以描述为:(ax) = ((ss)*16+(sp)),(sp) = (sp) + 2;

5.1.3 idata:

约定符号idata表示常量:

mov ax [idata]

5.1.4 [bx]相关代码:

mov ax,[bx]含义:(ax) = ((ds)*16+(bx))

5.2 Loop指令:

格式:loop 标号
CPU执行loop指令的时候,需要进行两步操作:
1.(cx) = (cx) + 1;
2.判断cx中的值,如果不为零则转至标号处执行程序,如果为零则向下执行。

通常cx中存放循环次数。

eg:计算2的11次方。

	mov ax,2
	mov cx,11
s:	add ax,ax
	......
	......
	loop s

在汇编源程序中,数据不能以字母开头,有时需要在前面加0。

5.3 Loop和[bx]的联合应用:

5.4 段前缀:

用于显式地指明内存单元的段地址的ds:cs:等。
mov ax,cs:[0]

5.5 一段安全的空间:

在一般的PC机中,DOS方式下,DOS和其他合法的程序一般都不会使用0:200~0:2FF的256个字节的空间。所以,我们使用这段空间是安全的。

5.6 段前缀的使用:

6. 包含多个段的程序:

6.1 在代码段中使用数据:

assume cs:codesg
codesg segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah.0987h
  start:mov bx,0
		mov ax,0
		mov cx,8
	  s:add ax,cs:[bx]
		add bx,2
		loop s
		mov ax,4c00h
		int 21h
codesg ends
end start

"start"的作用:让CPU从start的行开始读取。

6.2 在代码段中使用栈:

6.3 将数据、代码、栈放入不同的段:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值