汇编基础知识(未完)

160 阅读16分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

机器语言

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

机器指令展开来讲就是一台机器可以正确执行的命令。

指令:01010000(PUSH AX)

电平脉冲:

电平脉冲图.JPG

汇编语言的产生

汇编语言的主体是汇编指令

汇编指令和机器指令的差别在于指令的表示方法上。汇编指令是机器指令便于记忆的书写格式。

汇编语言是机器指令的助记符。

机器指令:100 010 011 101 110 00

操作: 寄存器BX的内容送到AX中

汇编指令: MOV AX, BX

寄存器:简单的讲就是CPU中可以存储数据的器件,一个CPU中有多个寄存器。

​ AX是其中一个寄存器的代号

​ BX是其中一个寄存器的代号

汇编语言的组成

汇编语言由三类组成

  1. 汇编指令(机器码的助记符)
  2. 伪指令 (由编译器执行)
  3. 其他符号 (由编译器识别)

汇编语言的核心是汇编指令,它决定了汇编语言的特性。

存储器

cpu 是计算机的核心部件,它控制整个计算机的运行并进行运算,

要想让一个cpu工作,就必须向它提供指令和数据。

  • 指令和数据在存储器中存放,也就是平时所说的内存。
  • 在一台PC机中存在的作用仅次于cpu
  • 离开了内存,性能再好的cpu也无法工作。
  • 磁盘不同于内存,磁盘上的数据或程序,如果不读到内存中,就无法被cpu使用

指令和数据

指令和数据是应用上的概念。

在内存或磁盘上,指令和数据没有任何区别,都是二进制信息。

二进制信息 :

1000 1001 1101 1000 ->89D8H(数据)

​ ->MOV AX, BX(程序)

存储单元

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

例如: 一个存储器有128个存储单元, 编号从0~127

对于大容量的存储器一般还用以下单位来计量容量(以下用B来表示Byte):

1KB = 1024B

1MB = 1024KB

1GB = 1024MB

1TB = 1024GB

磁盘的容量单位同内存的一样,实际上以上单位是微机中常用的计量单位。

cpu对于存储器的读写

cpu要想进行数据的读写,必须和外部器件(标准的说法是芯片)

进行三类信息的交互:

  1. 存储单元的地址(地址信息)
  2. 器件的选择,读或写命令(控制信息)
  3. 读或写的数据(数据信息)

cpu对存储器的读写

在计算机中专门有连接cpu和其他芯片的导线,通常称为总线。

物理上: 一跟跟导线的集合;

逻辑上划分为:

  1. 地址总线
  2. 数据总线
  3. 控制总线

总线在逻辑上划分的图示:

cpu对于存储器的读写.png 对于8086cpu,下面的机器码能够完成从3号单元读数据

机器码: 1010000 00000 11 00000000

地址总线

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

地址总线上能传送多少个不同的信息,cpu就可以对多个存储单元进行寻址。

一个cpu有N根地址总线,则可以说这个cpu的地址总线的宽度为N

这样的cpu 最多可以寻找2的N次方个内存单元。

数据总线

cpu与内存或其他器件之间的数据传送是通过数据总线来进行的

数据总线的宽度决定了cpu和外界的数据传书速度。

数据总线传输.JPG

控制总线

cpu对外部器件的控制是通过控制总线来进行的。在这里控制总线是个总称,控制总线是一些不同控制线的集合。

有多少根控制总线,就意味着cpu提供了对外部器件的多少种控制。

所以,控制总线的宽度决定了cpu对外部器件的控制能力。

前面所讲的内存读或写命令是由几根控制线综合发出的:

  1. 其中有一根名为读信号输出控制线负责由cpu向外传送读信号,cpu向该控制线上输出低电平表示将要读取数据;
  2. 有一根名为写信号输出控制线负责由cpu向外传送写信号。

内存地址和空间

一个cpu的地址线宽度为10, 那么可以寻址1024个内存单元,这个1024个内存单元就构成了这个cpu的内存地址空间。

主板

每一台PC机中,都有一个主板,主板上有核心器件和一些主要器件。

这些器件通过总线(地址总线,数据总线,控制总线)相连。

接口卡

计算机系统中,所有可用程序控制其工作的设备,必须受到CPU的控制

CPU对外部设备不能直接控制,如显示器,音箱,,打印机等。直接控制这些设备进行工作的是插在扩展插槽上的接口卡。

各类存储器芯片

从读写属性上来看分为两大类:

随机存储器(RAM)和只读存储器(ROM)

从功能和链接上分类:

  1. 随机存储器RAM
  2. 装有BIOS的ROM
  3. 接口卡上的RAM

装有BIOS的ROM

BIOS: Basic Input/Output System, 基于输入输出系统。

BIOS是由主板和各类接口卡(如:显卡, 网卡等)厂商提供的软件系统,可以通过它利用该硬件设备进行最基本的输入输出。在主板和某些接口卡上插有存储相应BIOS的ROM。

内存地址空间

  1. 都和CPU的总线相连
  2. CPU对它们进行读或写的时候都通过控制线发出内存对读写命令。

寄存器

cpu概述

一个典型的CPU由运算器,控制器,寄存器等器件组成,这些器件靠内部总线相连。

区别:

  1. 内部总线实现CPU内部各个器件之间的联系。
  2. 外部总线实现CPU和主板上其他器件的联系。

通用寄存器

8086CPU所有的寄存器都是16位的,可以存放两个字节。

AX,BX,CX,DX通常用来存放一般性数据被称为通用寄存器。

AX为例,看寄存器的逻辑结构。

通用寄存器.JPG 数据:18

二进制: 10010

在寄存器AX中的存储:

16位数据在寄存器中的存情况.JPG 8086上一代CPU中的寄存器都是8位的;未来保证兼容性,

这四个寄存器都可以分为两个独立的8位寄存器使用。

  1. AX可以分为AH和AL
  2. BX可以分为BH和BL
  3. CX可以分为CH和CL
  4. DX可以分为DH和DL

8086CPU的8位寄存器存储逻辑

以AX位例,8086CPU的16位寄存器分为两个8位寄存器的情况:(为了向下兼容)

寄存器寄存器中的数据所表示的值
AX010011100010000020000(4E20H)
AH0100111078(4EH)
AL0010000032(20H)

字在寄存器中的存储

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

就存在这个寄存器的高8位寄存器和低8位寄存器中

(每四个二进制的位可以用,一个十六进制来表示)

几条汇编指令

汇编指令不区分大小写

汇编指令控制CPU完成的操作用高级语言的语法描述
mov ax, 18将8送到AXAX = 18
mov ah, 78将78送到AHAH = 78
add ax, 8将寄存器AX中的数值加上8AX = AX+8
mov ax,bx将寄存器BX中的数据送入寄存器AXAX = BX
add ax, bx将AX,BX 中的内容相加, 结果存在AX中AX = AX + BX

(原AX中的值:0000H, 原BX中的值:0000H)

程序段中的指令指令执行后AX中的数据指令执行后BX中的数据
mov ax, 4E20H4E20H0000H
add ax, 1406H6226H0000H
mov bx, 2000H6226H2000H
add ax, bx8226H2000H
mov bx, ax8226H8226H
add ax, bx044CH(?)8226H
add al, 85H00C5H4026H
add al, 93H0058H(?)4026H

8226H+8226H != 1044CH

因为AX 分为 AL 和 AH 所以 00C5H+93H != 0158H

但是不会丢失进制精度

物理地址

CPU访问内存单元时要给出内存单元的地址。所有的内存单元构成的存储空间时一个一维的线性空间.

16位结构的CPU

概括的讲,16位结构描述了一个CPU具有以下几个方面特征:

  1. 运算器一次最多可以处理16位的数据
  2. 寄存器的最大宽度位16位
  3. 寄存器和运算器之间的通路是16位的。

8086CPU给出物理地址的方法

8086有20位地址总线,可传送20位地址,寻址能力位1M.

8086内部为16位结构,它只能传送16位的地址,

表示出的寻址能力却只有64k

8086CPU给出物理地址的方法.JPG

地址加法器互作原理

地址加法器合成物理地址的方法:

​ 物理地址 = 段地址*16+偏移地址

移位位数二进制十六进制十进制
010B2H2
1100B4H4
21000B8H8
310000B10H16
4100000B20H32

段的概念

错误认识: 内存被划分成了一个一个的段,每个一个段有一个段地址。

段地址概念.JPG

  1. 段地址*16 必然是16的倍数,所以一个段的起始地址也一定是16的倍数
  2. 偏移地址位16位,16位地址的寻址能力为64k, 所以一个段的长度最大为64k.

"数据在21F60H内存单元中。" 对于8086PC机的两种描述:

  1. 数据存在内存2000:1F60单元中;
  2. 数据存在内存的2000段中的1F60H单元中。

段寄存器

段寄存器就是提供段地址。

8086CPU有四个段寄存器:

CS: 代码段地址寄存器

DS:数据段地址寄存器

SS: 堆栈段地址寄存器

ES:其他的不够用所用的段地址寄存器

CS和IP

CS和IP是8086CPU中最关键的寄存器,它们指示了CPU当前要读

取指令的地址。

CS 为代码段寄存器

IP为指令指针寄存器(指向的是偏移地址)

同时修改CS,IP的内容

JMP 段地址:偏移地址 -》 JMP 2AE3:3 物理地址 2AE33H

​ -> JMP 3: 0B16 物理地址 0B46H

DEBUG

R命令查看,改变CPU寄存器的内容

D命令查看内存中的内容

E命令改写内存中的内容

U命令将内存中的机器指令翻译成汇编指令

T命令执行一条机器指令

A命令以汇编指令的格式在内存中写入一条机器指令。

寄存器(内存访问)

内存中字的存储

在0地址处开始存放20000 (4E20H)

内存中字的存储.JPG 字节型数据只占一个字节(8位数据)

字型数据占连续两个字节(16位数据)

DS和【address】

如何把1000H送入到ds?

传送指令mov ax, 1

相似的方式 mov ds,1000H (不能这么做) 属于硬件设计问题

数据-》通用寄存器-》段寄存器

mov bx, 1000H

mov ds, bx

mov [0], al

SUB是减法运算。

比如 mov ax,2 mov bx,1 sub ax,bx

其中sub ax,bx就是ax中的值减bx中的值,等于1,然后把结果,也就是1,放入ax中。

mov , add, sub指令

mov 通用寄存器, 数据 mov ax , 6

mov 通用寄存器, 寄存器 mov bx, ax

mov 通用寄存器, 内存单元 mov ax, [0]

mov 内存单元, 寄存器 mov [0], ax

mov 段寄存器, 寄存器 mov ds, ax

add 寄存器, 数据 add ax, 8

add 寄存器, 寄存器 add ax, bx

add 寄存器, 内存单元 add ax, [0]

add 内存单元, 寄存器 add [0], ax

sub 寄存器, 数据 sub x, 9

sub 寄存器, 寄存器 sub ax, bx

sub 寄存器, 内存单元 sub ax, [0]

sub 内存单元, 寄存器 sub [0], ax

比如我们用123B0H~~~123B9H这段空间来存放数据

段地址: 123BH

长度:10字节

CPU提供的栈机制

现今的CPU中都有栈的设计

8086CPU提供相关的指令来以栈的方式访问内存空间

8086CPU提供入栈和出栈指令:

PUSH(入栈)

POP(出栈)

push ax: 将寄存器ax中的数据送入栈中

pop ax: 从栈顶取出数据送入ax

8086CPU的入栈和出栈操作都是以字为单位进行的

注意:字型数据用两个单元存放,高地址单元放高8位,低地址单元放低8位。

CPU如何指导当前要执行的指令所在的位置?

寄存器CS和IP中存放着当前指令的段地址和偏移地址。

8086CPU中,有两个寄存器:

​ 段寄存器SS 存放栈顶的段地址

​ 寄存器SP 存放栈顶的偏移地址

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

push ax

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

PUSH指令的执行过程1.JPG

PUSH指令的执行过程2.JPG

PUSH指令的执行过程3.jpg

段寄存器都是以s结尾的,通用寄存器都是以x结尾的

push, pop指令

push和pop指令的格式

push内存单元:将一个内存单元处的字入栈(栈操作都是以字为单位)

pop内存单元: 出栈,用一个内存字单元接受出栈的数据

例如: push[0] pop[2]

指令执行时,cpu要知道内存单元的地址,可以在push, pop指令中给出内存单元的偏移地址,段地址在指令执行时,cpu从ds中取得。

mov ax,1000H

mov ss,ax

mov sp, 0010H

mov ax, 002AH

mov bx, 002BH

push ax

push bx

pop ax 就是把栈顶的bx放入ax中

pop bx 就是把栈中的ax放入bx中

第一个程序

我们将开始编写完整的汇编语言程序,用编译器将他们编译成为可执行文件(如:*.exe文件),在操作系统中运行。

  1. 使用汇编语言编译程序(MASM.EXE)对源程序文件中的源程序进行编译,产生目标文件;
  2. 再用链接程序(LINK.EXE) 对目标文件进行链接,生成可在操作系统中直接运行的可执行文件。

可执行文件

可执行文件中包含两部分内容:

程序(从原程序中的汇编指令翻译过来的机器码)

数据(源程序中定义的数据)

源程序

汇编指令: 有对应的机器码的指令,可以被编译位机器指令,最终位CPU所执行

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

谁来执行伪指令呢?

伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作。

定义一个段

segment和ends是一对成对使用的伪指令,这是在写可被编译器编译的汇编程序时,必须要用到的一对伪指令。

end是一个汇编程序的结束标记,编译器在编译汇编程序的过程中,如果碰到了伪指令end,就结束对源程序的编译。

assume: 含义为假设

它假设某一段寄存器和程序中的某一个用segment ... ends 定义的段相关联。

汇编程序:

​ 伪指令 (编译器处理)

​ 汇编指令 (编译为机器码)

程序:源程序中最终由计算机执行,处理的指令或数据。

将源程序文件中的所有内容称为源程序,将源程序中最终由计算机执行处理的指令或数据,成为程序。

程序最先以汇编指令的形式存在源程序中,经编译链接后转变为机器码,存储在执行文件中。

源程序

任务:编程运算2的3次方

abc segment

mov ax,2

add ax,ax

add ax,ax

abc ends

end

目的相关指令指令性质指令执行者
通知编译器一个段结束段名 ends伪指令编译时,由编译器执行
通知编译器程序结束end伪指令编译时,由编译器执行
程序返回mov ax,4c00H
int 21H
汇编指令编译时由CPU执行

未完待续

(推荐)有点编程基础的

b站小甲鱼,我看的是这个up主的汇编

学jvm去看b站尚硅谷看宋红康的

计算机组成原理(b站去看哈工大的)

操作系统(b站去看哈工大的)

计算机网络(b站去看哈工大的)

数据结构我比较菜,就不推荐了。

点个赞吧!讨生活啊,大哥大姐们。