1.基础知识:
1.1
存储器中指令和数据都是二进制信息
cpu可使用的信息在存储器(机器指令)
存储器的单位是存储单元,一个单元能存一字节1b=8bit(8个01的数)
cpu有许多管脚(接口),和总线(address,data,control 总线)相连
1.2 存储器:
一个cpu的 地址线宽为10,能寻址2^10=1kb空间(1024个存储单元)
ROM(只读存储)========里面放着电脑各个卡(网卡,声卡,显卡。。。)的驱动程序(软件系统BIOS=====软硬件沟通的桥梁,其实就是二进制程序,不过这个二进制程序是主板的厂商写的硬件接口)
RAM 我们说增加内存条,就是为主板增加一个RAM
cpu知道RAM和ROM的地址空间
汇编语言是面向cpu编程,cpu寻址是在统一的逻辑存储器(连续的内存地址空间)中寻址
备注:vc6的一个题: int q=5;q=(++q)+(++q)+(++q) 结果q=7+7+8=21 编译分析 自增1,丢掉寄存器,再递增1,丢掉寄存器,然后cpu才计算这两个值的和
1.3 寄存器
AX,BX,CX,DX(存放一般性数据:通用寄存器) X代表16进制(这里是16位寄存器的意思=============能存放16个01的二进制数,32位的寄存器是EAX:extra AX【扩展的AX】)
十进制的20000在AX中的存储:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 0 0 1 1 1 0 0 0 1 0 0 0 0 0
然后15~8有可以用独立的8位寄存器表示:AL即AX的高位
7 6 5 4 3 2 1 0
0 1 0 0 1 1 1 0
一个字(8位的bit)在8位寄存器中占1B(1字节)
一个字(8位的bit)在16位寄存器中占2B(2字节)========AH字节+AL字节
为了区分不同进制:16后加H,表示这是16进制数,二进制加B,十进制啥也不加
20000 ——————————4E20H -------------------------- 0 1 0 0 1 1 1 0 0 0 1 0 0 0 0 0 B
1.4汇编指令:(汇编不区分大小写)
汇编指令 | 控制cpu完成的操作 | 高级语言的描述 |
mov ax 18 | 将18送入ax | AX=18 |
mov ah 78 | AH=78 | |
mov ax bx | 将寄存器BX中的数据送到AX中 | AX=BX |
add ax bx | AX,BX内容相加,结果存在AX中 | AX=AX+BX |
备注:在cpu看来,所有的内存地址都是一个一维的线性排列,也叫逻辑地址(长的很逻辑,就是很线性的意思。)
1.5 cpu是怎么寻址的:
cpu物理结构:
cpu核心的基本单位:晶体管:(cpu的一个核心由上亿个晶体管组成)
中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路(本质)
cpu从物理结构是由基板+针脚+核心构成,==================一个cpu可能有多个核心:
单核和双核区别:10000*10000 单核是智商150的独立计算(一次只能处理一个进程) 双核是2个智商100的来共同计算(一次能处理二个进程)
cpu内核(cpu核数就是指内核的个数)=运算器(ALU+FLU)+控制器(指令控制器+时序控制器+总线控制器+中断控制器)+寄存器【累加寄存器,MQ乘商寄存器...........】
cpu外核=解码器(长度不定的x86指令转换为长度固定的指令,并交由内核处理)+缓存(一级缓存和二级缓存)
cpu=cpu外核+cpu内核
20位物理地址加法器由20位二进制代码组成,20位物理地址=16位段地址×10H+段内偏移地址
cpu寻址(地址解码器负责完成16位二进制数与20位二进制数的转换)
16进制数*16表示(该数向左移动一位,二进制就要向左移4位)===========类比10进制: 10*10=100(1向左移动了一位) 10*10*10=1000(1向左移动了2位)
学校走2000m到体育馆,在走800m就到图书馆 2000m(基地址)+800m(偏移地址)=最终地址 【这种方式扩大了cpu的寻址能力】
内存是连续的,内存的地址是线性的,他没有基址+偏移址的概念,内存认为:学校到图书馆的地址是2800m
cpu认为:学校到图书馆的地址是2000m+800m
1.6 段寄存器:
存放段地址的叫段寄存器
1.7 计算
通用寄存器AX,BX中的值可通过mov移动指令来修改 mov ax,200H ax中的值此时为200H
段地址CS寄存器和偏移地址IP寄存器中的值需要通过jmp指令来修改 jmp 200H:3H CS中的值在此次操作中为200H,IP中的值在此次操作中为3H
仅修改IP的值:jmp ax 此时IP寄存器中的值就由3H变成了200H
段CS寄存器的大小为2^16bit=64k 代码段就是一系列地址的意思,int a; int b;=============a在内存中的地址0000H,b在内存中的地址0010H。单核的cpu只有一个AX,他的大小是64k,数据是临时存储的,新来的数据会覆盖原来的数据
32位windows和linux都是保护模式os,所以不能随意访问地址,16位的window是实模式os,可以随意访问地址,(但是32位window能在cmd随意访问地址。还可以跑16位程序,是因为有个内置的虚拟机,所以不会影响系统,16位windows就有可能搞崩系统)
20000(4E20H) 在0地址处开始存放(0是低位,低对低)
0 1 2 3 4 5 6
20H 4EH
任何连续的内存单元,都可以看成是高位+地位
mov al,[0] 将内存单元【0】的内容送入寄存器中,【】表内存单元,0表示内存单元的偏移地址,内存单元的段地址在ds寄存器中。
数据--->通用寄存器--------->段寄存器 数据和段寄存器之间没有直达的物理电路(所以数据----段寄存器是非法的)
16位出现了字,32位出现了双字
1.8 栈:
push ax ax中的数据入栈
pop ax 从栈顶取出数据送入ax
mov ax 0123H
10000H
............
10000CH
10000DH
10000EH 01
10000FH 23 栈底
字形数据用两个单元存放,高地址放高8位,低地址放低8位
哪段内存空间被当作栈来使用
ss段寄存器 存放栈顶的段地址
sp寄存器 存放栈顶的偏移地址
ss:sp指向栈顶 在下一个push之前,执行sp=sp-2 ==================ss:sp指向10000CH
pop出栈:
sp=sp+2 ss:spss:sp指向10000EH,注意,10000CH的数据仍然存在,当下一次push时,sp=sp+2,新来的数据会将原来的数据覆盖(本质是通过覆盖达到删除)
程序员分配的是堆空间(零碎的空间,由线性表组合关联起来)
栈是内存的一部分,他只是一段可以以特殊方式访问的内存空间
练习:将ax,bx,ds中的数据入栈:
mov ax,1000H
mov ss,ax 栈的段地址
mov sp,0010H 栈顶偏移地址
push ax
push bx
push ds
先设置栈定地址,再将数据通过中转(通用)寄存器,mov到栈中
数据段,代码段,栈有栈段(栈空间一般为64kb)
如果栈满,还有入栈,栈顶将循环覆盖原来的内容
.exe 多个段和多个栈 .com 一个段和一个栈