汇编语言笔记

最近将汇编粗略的复习了下,作个简单记录:


1,基础知识
2,寄存器
3,寄存器(内存访问)
4,第一个程序
5,[BX]和loop指令
6,包含多个段的程序
。。。


第一章 基础知识
1,用汇编语言编写程序的过程如下图所示:


2,汇编语言发展至今,有以下3类指令组成:
汇编指令:机器码的助记符,有对应的机器码。
伪指令:没有对应的机器码,由编译器执行,计算机并不执行。
其它符号:如+、-、*、/等,由编译器识别,没有对应的机器码。
汇编语言的核心是汇编指令,它决定了汇编语言的特性。

3,每一种CPU都有自己的汇编指令集。CPU可以直接使用的信息在存储器中存放。

4,在存储器中指令和数据没有任何区别,都是二进制信息。存储单元从零开始顺序编号。一个存储单元可以存储8个bit,即8位二进制数。

5, 1Byte=8bit  1KB=1024B  1MB = 1024KB  1GB = 1024MB

6,每一个CPU芯片都有许多管脚,这些管脚和总线相连。也可以说,这些管脚引出总线。一个CPU可以引出3种总线的宽度标志了这个CPU的不同方面的性能:

地址总线的宽度决定了CPU的寻址能力;
数据总线的宽度决定了CPU与其它器件进行数据传送时的一次数据传输量;
控制总线的宽度决定了CPU对系统中其它器件的控制能力。

7,CPU系统中各类存储器看作一个逻辑存储器,如下图所示。

8,不同的计算机系统的内存地址空间的分配情况各不相同。8086PC机内存地址空间分配情况如下图所示:


2.第二章 寄存器

1,一个典型的CPU由运算器、控制器、寄存器等器件构成。运算器进行信息处理;寄存器进行信息存储;控制器控制各种器件进行工作;内部总线连接各种器件,在它们之间进行数据的传送。

2,8086 CPU有14个寄存器,每个寄存器都有一个名字:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW

3,通用寄存器:AX、BX、CX、DX,用于存储一般性的16位数据。这4个寄存器又可以各自分为两个独立的8位寄存器来用:AH和AL;BH和BL、CH和CL、DH和DL。数据存储情况如下所示:


4,字节:记为byte,一个字节由8个bit组成,可以存储在8位寄存器中。字:记为word,一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节。

5,几条汇编指令举例:


6,16位结构的CPU可以按照如下描述:
运算器一次最多可以处理16位的数据;
寄存器的最大宽度为16位;
寄存器和运算器之间的通路为16位。

7,8086CPU有20位地址总线,可以传送20位地址,达到1MB寻址能力。而8086CPU又是16位结构,所以,8086CPU采用一种在内部用两个16位地址合成的办法来形成一个20位的物理地址,相关部件的逻辑结构如下图说所示:


1)CPU中的相关部件(CS和IP)提供两个16位的地址,一个称为段地址,另一个称为偏移地址;
2)段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
3)地址加法器将两个16位地址合成为一个20位的物理地址:物理地址 = 段地址x 16 + 偏移地址 
4)地址加法器通过内部总线将20位物理地址送入输入输出控制电路;
5)输入输出控制电路将20位物理地址送上地址总线;
6)20位物理地址被地址总线传送到存储器。

8,CS和IP是8086CPU中两个最关键的寄存器,它们指示了CPU当前读取指令的地址。CS为代码段寄存器,IP为指令指针寄存器。在8086CPU机中,任意时刻,设CS中的内容为M,IP中的内容为N,8086CPU将从内存Mx16+N单元开始,读取一条指令并执行。

9,8086CPU的工作过程简述如下:
Step1: 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
Step2:IP=IP+所读取指令的长度,从而指向下一条指令;
Step3:指令执行。转至step1,重复这个过程。

10,修改CS、IP的指令
a)jmp 段地址:偏移地址  -> 用指令中给出的段地址修改CS,偏移地址修改IP。
b)Jmp 某一合法寄存器    -> 仅修改IP的内容

第三章 寄存器(内存访问)
1,子单元,即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数的高位字节,低地址内存单元中存放字型数据的低位字节。起始地址为N的字单元简称为N地址字单元。

2,DS和[address]。8086CPU有一个DS寄存器,通常用来存放要访问数据的段地址。用mov指令访问内存单元,可以再mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。示例代码如下:将1000H(1000:0)中的数据读入到al中。至于为何不直接将1000H送入ds,即mov ds,1000H,这是8086CPU硬件设计的问题。

mov bx,1000H
mov ds,bx
mov al,[0]

3,mov指令
mov:寄存器,数据
mov:寄存器,寄存器
mov:寄存器,内存单元
mov:段寄存器,内存单元
mov:内存单元,寄存器
mov:内存单元,段寄存器
mov:段寄存器,寄存器
mov:寄存器,段寄存器

4,add指令
add:寄存器,数据
add:寄存器,寄存器
add:内存单元,寄存器
add:寄存器,内存单元

4,sub指令
sub:寄存器,数据
sub:寄存器,寄存器
sub:内存单元,寄存器
sub:寄存器,内存单元

 
5,jmp指令
jmp:段地址:偏移地址  用段地址修改CS 用偏移地址修改IP
jmp:寄存器,只用寄存器的内容修改IP

6,在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。

7,mov、add、jmp是具有两个操作对象的指令。jmp是具有一个操作对象的指令。

8,栈:LIFO(Last In First Out,后进先出)。

9,8086CPU出栈入栈都是以字为单位进行的;在SS、SP中存放栈顶的段地址和偏移地址;任意时刻,SS:SP指向栈顶元素;push指令(入栈)和pop指令(出栈)执行时,CPU从SS和SP中得到栈顶的地址;8086CPU只记录栈顶,栈空间的大小我们要自己管理;push、pop实质上是一种内存传送指令。

10,push ax 由一下两步完成
1)SP=SP-2
2)将ax中的内容送入SS:SP指向的内存单元

11,pop ax 
1)将SS:SP指向的内存单元中的内容送入ax
2)SP=SP+2

12,push/pop其它
push 寄存器
pop 寄存器
push 段寄存器 
pop 段寄存器
push 内存单元
pop 内存单元
只给出内存单元的偏移地址,段地址在指令执行时从ds中获得。

13,段的综述
++++++++++++++++++++++++
为了编程的方便,人为的将一段内存定义为一个段:用一个段地址指示段,用偏移地址访问段内的单元。
比如,用一个段存放数据,将它定义为“数据段”;用一个段存放代码,将它定义为“代码段”;用一个段当作栈,将它定义为“栈段”。

对于数据段,将它的段地址放在DS中,用mov、add、sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当作数据来访问;
对于代码段,将它的段地址放在CS中,将段中第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令;
对于栈段,将它的段地址放在SS中,将栈顶单元的偏移地址放在SP中,这样CPU在需要进行栈操作的时候,比如执行push、pop指令等,就将我们定义的栈段当作栈空间来用。

可见,不管我们如何安排,CPU将内存中的某段内容当作代码,是因CS:IP指向了那里;CPU将某段内存当作栈,是因为SS:SP指向了那里。我们要清楚,什么是我们的安排,以及如何让CPU按我们的安排行事。

一段代码,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么也不是。关键在于寄存器的设置,即CS、IP,SS、SP,DS的指向。
++++++++++++++++++++++++

第四章 第一个程序
1,segment 和ends是一对成对使用的伪指令,用于定义一个段。segment说明一个段开始,ends说明一个段结束。如下的Xxx为段的名称。

Xxx segment
...
Xxx ends

2,伪指令end是一个汇编程序的结束标记。注意区别ends(与segment是成对使用的)。

3,伪指令assume含义为“假设”,即假设某一段寄存器和程序中的某一个用segment...ends定义的段相关联。

4,与结束相关的概念


5,汇编程序从写出到执行的全部过程如下:


 

第五章 [BX]和loop指令

1,mov ax, [bx]  功能:bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将SA:EA处的数据送入ax中。即:(ax)=((ds)*16+(bx))。

2,mov [bx], ax 功能:bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将ax中的数据送入内存SA:EA处。即:((ds)*16+(bx))=(ax)。

3,用cx和loop指令相配合实现循环功能的程序框架如下:

  mov cx, 循环次数
s: 
  循坏执行的程序段
  loop s

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

第六章 包含多个段的程序

1,段名相当于一个标号,它代表了段地址。所以,“mov ax,data”就是将名为data的段的段地址送入ax.

assume cs:code,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
code segment    
start:    mov ax,stack
        mov ss,ax
        mov sp,16    ;将设置栈顶ss:sp指向stack:16
        
        mov ax,data
        mov ds,ax    ;ds指向data 
        
        mov bx,0    ;ds:bx指向data段中第一个单元
        mov cx,8
    s:    push [bx]
        add bx,2
        loop s        ;将以上代码段0-16单元中的8个字符型数据依次入栈
        
        mov bx,0
        mov cx,8
    s0:    pop [bx]
        add bx,2
        loop s0        ;以上依次出栈8个字符型数据到代码段0-16单元中
        
        mov ax,4c00H
        int 21h
code ends
end start            ;指名程序的入口在start处

。。。。。。

参考:
1,《汇编语言》-王爽,清华大学出版社
2,  汇编网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值