type
status
date
slug
summary
tags
category
icon
password
以下学习内容 from 王爽汇编语言(第三版

一,计算机组成

1.CPU

CPU是计算机的核心部件,它控制整个计算机的运作并进行运算。想要让一个CPU工作,就必须向它提供指令和数据(from 存储器)

2.存储器(内存)

指令和数据存储器(内存)中存放。离开了内存,CPU无法工作

3.指令和数据的表示

问:二进制信息1000100111011000是数据还是指令?
其实这个要看CPU,如果看作89D8H,则是数据,如果看作MOV AX,BX,则是指令

4.计算机中的存储单元

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

5.计算机中的总线

在计算机中有专门有链接CPU和其他芯片的导线,通常称为总线(一根根导线的集合)
  • 三类总线:
  1. 地址总线 CPU是通过地址总线来指定存储单元的; 地址总线的宽度,决定了可寻址的存储单元大小; N根地址总线(宽度为N),对应寻址空间为2**N
  1. 数据总线 CPU与内存或其它器件之间的数据传送时通过数据总线来进行的; 数据总线的宽度决定了CPU和外界的数据传送速度; 例如:向内存中写入数据89D8H时,8位数据总线要传送两次(第一次00011011 D8 ;第二次10010001 89);而16位数据总线只用传送一次(1001000100011011 89D8)
  1. 控制总线 CPU通过控制总线对外部期间进行控制; 控制总线时一些不同控制线的集合; 控制总线的宽度决定了CPU对外部器件的控制能力
CPU
地址总线宽度
寻址能力
数据总线宽度
一次传送数据
读取1KB数据要读X次
8086
20
1MB(2**20)
16
2B
512
80286
24
16MB(2**24)
16
2B
512
80386
32
4GB(2**32)
32
4B
256

6.CPU对存储器的读写

三类信息交互: 1. 存储单元的地址(地址信息) 2. 器件的选择,读或写的命令(控制信息) 3. 读或写的数据(数据信息)
  • 演示
机器码:1010000000000001100000000
16进制:A0030
汇编指令:MOV AL,[3]
含义:从3号单元读取数据送入寄存器AL
notion image
  • 过程:
CPU先通过地址线将要读取的地址信息[3]送入内存,锁定3号单元; 再通过控制线将控制信息‘读’传送到内存; 最后将3号单元内的数据08通过数据线传给CPU

7.内存地址空间

  • 什么时内存地址空间?(以8086为例) 8086CPU地址总线宽度为20,可以寻址1MB个内粗你单元,那么内存地址空间为1MB
notion image
 

二.访问寄存器和内存

1.寄存器及数据存储(指令)

8086CPU有14个寄存器:

通用:AX、BX、CX、DX 变址:SI、DI 指针:SP、BP 指令指针:IP 段:CS、SS、DS、ES 标志:PSW
共性:都是16位,可以存放两个字节,最大值:2**16-1

mov和add、sub指令

汇编指令
CPU完成的操作
描述
mov ax,18
将18送入AX
AX = 18
mov ax,bx
将寄存器BX里的数据送入寄存器AX
AX = BX
add ax,8
将寄存器AX中的数据加8
AX += 8
add ax,bx
将AX,BX中的内容相加,存在AX中
AX = AX + BX
sub ax,18
将寄存器AX中的数据减18
AX -= 18
sub ax,bx
将寄存器AX的值减去BX的值
AX = AX - BX
特殊:通用寄存器可以拆为两个8位寄存器表示,比如AX,可以拆为AH(高位)和AL(低位)
mov操作是‘送入’,没有加的意思。比如一开始AX寄存器中的数据为2640H,经过汇编指令mov AH,0后,变为0040H

jmp指令

8086CPU大部分寄存器的值,都可以用mov指令(传送指令)来改变 但是,mov指令不能用于设置CS、IP的值
能改变的指令是jmp指令(转移指令)
  • 同时修改CS、IP的内容 jmp 段地址:偏移地址
  • 仅修改IP的内容 jmp 某一合法寄存器
分析一个问题:
notion image
  • 从20000H开始,执行的序列是:
(1) mov ax,6622
(2) jmp 1000:3
(3) mov ax,0000
(4) mov bx,ax
(5) jmp bx
(6) mov ax,0123H
(7) 跳转至第(3)步执行(至此循环)

inc指令

加一的意思

Loop指令

功能:实现循环(计数型循环)
执行时要执行的操作:
  1. CX = CX -1 (因此CX寄存器又被称为计数寄存器)
  1. 判断CX中的值,不为0则继续跳转;为0则向下执行
notion image
这段汇编代码作用实现2**12

2.确定物理地址的方法

8086CPU有20位地址总线,可以传送20位地址,寻址能力1M 但8086是16位结构的CPU,运算器一次最多可以处理16位数据,寄存器最大宽度也是16位,所以内部处理、传输、暂存的地址也是16位,寻址能力只有64KB

8086如何处理寻址空间上的矛盾?

用两个16位地址(段地址、偏移地址)合成一个20位物理地址
地址加法器合成物理地址的方法:物理地址 = 段地址 x 16 + 偏移地址 段地址 x 16其实是十六进制段地址数据左移一位
  • 同一段内存,可以有多种分段方案
notion image
起始地址(基础地址)为10000H,段地址为1000H,大小为100H
notion image
起始地址为10000H和100080H,段地址为1000H和1008H,大小均为80H
  • PS: 段地址 x 16必然是16的倍数,所以一个段起始地址一定是16的倍数 偏移地址为16位,寻址能力64k,所以一个段最大长度64k

段地址很重要,所以专门寄存器存放段地址

CS—代码段寄存器
DS—数据段寄存器
SS—栈段寄存器
ES—附加段寄存器

3.段总结

段基础

物理地址 = 段地址 x 16 + 偏移地址

做法

可以根据需要将一组内存单元定义为一个段;
起始地址为16的倍数,长度为N(N≤64K)的一组地址连续的内存单元定义为一个段;
将一段内存定义为一个段后,用一个段地址指示段,用偏移地址访问段内的单元(自由安排)

4.CS和IP寄存器

CS—代码段寄存器,IP—指令指针寄存器(表示方法:CS:IP)
IP寄存器存的是偏移地址
notion image
 

5.内存中字的存储

对8086CPU,16位作为一个字。存储在一个16位的寄存器中,高8位放高字节,低8位放低字节

6.CPU从内存单元中读取数据

读取一个内存单元时,必须先给出这个内存单元的地址
原理:在8086PC中,内存地址由段地址和偏移地址组成(段:偏移)
解决方案:DS寄存器和[address]配合 DS寄存器存放要访问的数据的段地址 偏移地址用[……]形式直接给出
特殊:段地址送入DS:数据→一般的寄存器→段寄存器(重要)
字的传送
8086CPU可以一次性传送一个字(16位数据)

DS与数据段

  1. 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中;
  1. 用mov指令要访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中;
  1. [address]表示一个偏移地址为address的内存单元

7.栈结构

  • 栈时一种只能在一段进行插入或删除操作的数据结构

两个基本操作:入栈和出栈

入栈(PUSH):将一个新的元素放到栈顶 出栈(POP):从栈顶取出一个元素
push ax:将ax中的数据送入栈中 pop ax:从栈顶取出数据送入ax
以上操作以为单位对栈进行操作
栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。操作规则:LIFO(Last In First Out,后进先出)

CPU提供的栈机制:

提供栈相关指令,支持用栈的方式访问内存空间;可以将一段内存当作栈来使用
试例:设将10000H~1000FH内存当作栈来使用
notion image
根据图内指令序列,先将0123H存入ax寄存器,然后将ax内的数据入栈,此时1000FH中的数据为01,1000EH中的数据为23; 同理操作,最后pop出来时从栈顶(在这个例子中是1000AH)出栈依次存入ax,bx,cx

CPU如何知道一段内存空间被当作栈使用?

需要有两个与栈相关的寄存器: 栈顶寄存器SS:存放栈顶的段地址 栈顶指针寄存器SP:存放栈顶的偏移地址
栈空时,SS:SP指向栈顶10010H
notion image

push指令和pop指令的执行过程

push、pop指令实质上是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的
  1. push ax (1),SP = SP - 2; (2)将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶
  1. pop ax (1)将SS:SP指向的内存单元处的数据送入ax中; (2)SP = SP + 2, SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶
栈满时,使用push执行会发生栈顶超界问题 栈空时,使用pop执行也会发生栈顶超界问题
 

三、汇编语言程序

  • 汇编程序由汇编代码和伪指令组成。没有对应的机器码的指令,最终不会被CPU所执行
  • 伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作

1.程序中的三种伪指令

段定义

一个汇编程序是由多个段组成的,这些段被用来存放代码、数据或当作栈空间来使用(一个有意义的汇编程序至少要有一个段,用来存放代码)
定义程序中的段:每个段都需要有段名

end(不是ends)

汇编程序的结束标记。若程序结尾处不加end,编译器在编译程序时,无法知道程序何处结束

assume(假设)

假设某一段寄存器和程序中的某一个用segment…ends定义的段相关联—assume cs:codesg指CS寄存器与codesg关联,将定义的codesg当作程序的代码段使用

2.写出一个程序的过程

notion image
notion image
notion image
notion image
notion image
  1. 首先要定义一个段
  1. 再实现处理任务(汇编指令)
  1. 指出程序在何结束(end)
  1. 段与段寄存器关联
  1. 加上程序返回代码

3.[…]的规定与(…)的约定

[…]——汇编语法规定,表示一个内存单元

举个例子:
mov ax,[bx] ——指的是(ax) = (ds * 16 + (bx))
notion image

(…)——为学习方便做出的约定,表示一个内存单元或寄存器中的内容

描述方法:(…)里面只能用寄存器及物理地址

再约定:符号idata表示常量(段前缀)

在[idata]前显示地协商段寄存器(加上段前缀)
mov al,ds[bx] ——与mov ax,[bx]表示一样 小小总结一下:
notion image

4.访问连续的内存单元—loop和[bx]

 
VenomCTF2024 reverseBUUCTF(持续更新ing)
Loading...
Sh4d0w
Sh4d0w
漫长学习路ing
最新发布
360加固复现学习
2025-6-15
java反射机制
2025-6-14
classLoader机制
2025-6-14
dex文件结构
2025-6-14
APP启动流程
2025-6-14
JNI学习
2025-6-14
公告
Welcome to Sh4dw’s blog!
敬请指导,Q 467194403