进制转换基础
- 计算机只识别二进制,汇编中一般是用十六进制表示数据,是用十六进制是为了方便程序员阅读和开发。
- 二进制和十六进制转换
0101 1100 1001 0010 //二进制
5 c 9 2 //每四位二进制数对应一位十六进制数
① 在X86汇编代码中,十六进制写法为如下:
mov ax,2000H ; h结尾表示十六进制,h不区分大小写
② 在ARM汇编代码中,十六进制写法为如下:
Mov R0,#0x2020202A ; 使用0x开头表示 #是固定写法
数据单位
- 位:一个二进制位
- 字节:8个二进制位表示一个字节
由于八个二进制位转换成十六进制后是两位十六进制数,所以两个十六进制数占用一个字节:
0x20 ;占用一个字节
20H ;占用一个字节
在计算机中最小的数据单位是位,但在内存中,最小的数据单位是字节,一个内存单元占用一个字节,内存单元就是一个存放数据的容器,可以比喻为一栋公寓里面的小单间,每个单间住着一对夫妻。
内存单元和地址
内存单元相当于一栋公寓里面的小单间,每个单间里面住着一个字节(一对夫妻),一对夫妻是两个人,形容两个十六进制数。
地址就相当于这个房间的门牌号,通常使用十六进制表示(也叫物理地址)。
CPU想要读写内存中的数据,需要通过地址找到对应的内存单元,也叫寻址。
内存条容量:既然每个单元占的空间是固定的,那么内存容量越大,房间自然就越多。
给房间贴门牌号
0x1 |
0x2 |
0x3 |
…… |
0x10 |
0x20 |
…… |
0x100 |
0x200 |
…… |
0x1000 |
0x2000 |
…… |
0xFFFF 65535 |
在计算机中,地址编码最大值和什么有关?
- CPU运算能力
- 地址总线宽度(地址总线数量)
- 如果对应的CPU是16位的,同时地址总线也是16位的,那么最大只能运算表示16位数也就是0xFFFF。
- 如果对应的CPU是32位的,同时地址总线也是32位的,那么最大只能运算表示32位数也就是0xFFFFFFFF。
- 如果对应的CPU是64位的,同时地址总线也是64位的,那么最大只能运算表示64位数也就是0xFFFFFFFFFFFFFFFF。
在8086CPU中,CPU是16位的,但是地址总线却是20位的,本来最大只能表示16位地址值,CPU设计者为了让其能表示20位地址,使用了段地址*16+偏移地址的形式来表示20位地址。
物理地址=段地址*16+偏移地址
如果要表示一个20位物理地址0xFFFFA,可以有以下四种写法:
- 0xFFFFA=0xFFFF0*16+0x000A //FFFF0 10*10=100
- 0xFFFFA=0xFFF00*16+0x00FA
- 0xFFFFA=0xFF000*16+0x0FFA
- 0xFFFFA=0xF0000*16+0xFFFA
因此计算机的寻址能力不单单和CPU有关还和地址总线有关,32位操作系统对应32位地址总线,这也是为什么即使你用的是64位CPU,如果只装了32位操作系统,无法完全发挥CPU和内存的性能。
栈和队列
栈和队列都是数据存储结构,数据结构大致包含以下几种存储结构:
- 线性表:还可以细分为顺序表、链表、栈和队列。
- 树结构:包括普通树、二叉树、线索二叉树。
- 图存储结构
- 队列结构:先进先出,和排队一样。
- 栈存储结构:先进后出,类似于往杯子里放饼干,第一个放的最后一个取出。
栈作用:用于临时存放数据,对数据进行暂时性保护,不被复写。
寄存器和栈同样用于存放临时数据,二者之间的区别为:
- 寄存器类似于全局变量,是个公共容器,可以被所有函数读写,寄存器中的数据容易被覆盖,常用于短周期使用。
- 栈空间是累加型结构,如果想要复写第一个放入的数据,必须先将后面存放的数据丢弃,类似于递归,适合嵌套数据,这也是为什么函数和函数中的局部变量都存放在栈中的原因。
X86汇编语言之通用寄存器的数据读写
1.注释:
; 我是注释
2.变量取值和赋值(传送指令):
; 赋值
mov ax,2000H ; 将十六进制2000赋值给十六位寄存器ax 相当于ax=2000H
; 取值
mov bx ,ax ; 将ax中的值取出赋值给bx 相当于bx=ax
存放的数据大小根据使用的寄存器而定,比如ax是十六位寄存器,最大只能存放十六位数据,也就是4位十六进制数据。
十六进制数据不能以字母开头,前面需加上0否则编译报错
3.函数声明
结构如下:
函数体
ret ;结尾标记
示例:
print: 函数名
mov dx,offset str
mov ah, 9ch
int 21h
ret ; 函数结尾标记
4.函数调用:
X86架构中使用关键指令call
X86架构汇编示例:
call print ;调用print函数
; 退出程序
mov ah, 4ch
int 21h
Print ;函数名
mov dx,offset str ;获取别名对应数据的偏移地址
mov ah, 9ch ; 9ch表示调用显存 从dx总读取偏移地址对应的数据
int 21h
ret