汇编语言_1 计算机基础;寄存器

Posted 灰海宽松

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编语言_1 计算机基础;寄存器相关的知识,希望对你有一定的参考价值。

基础知识

早期机器语言:01打孔。

汇编语言:机器语言便于记忆的格式。通过编译器替换为机器码。

寄存器:cpu 中的存储器。比如汇编中 AX BX 就是寄存器的代号。

存储器中的存储单元是 8 bit,从0开始顺序编号。

汇编语言的组成

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

核心部分是汇编指令。

CPU 读写存储器

需要知道:存储器地址,器件的控制命令,读写的数据。

CPU 连接其他芯片的线叫做总线,分为地址、数据、控制总线。

地址总线的宽度决定了寻址能力,数据总线的宽度决定了数据传送速率,控制总线的宽度决定了有多少种控制指令。

内存

(汇编编程要从 CPU 角度出发)

对于 CPU 来说,看到的就是各个 RAM ROM 对应的地址空间。所有存储单元对 CPU 来说都处于一个统一逻辑存储空间中,也就是内存地址空间。

寄存器

CPU 内部总线连接内部的运算器、控制器、寄存器,外部总线实现 CPU 和主板上其他部件的联系。

以 8086CPU 为例,所有寄存器都是16位两字节的。其中存放一般数据的是通用寄存器,如 AX BX CX DX .

8086CPU 上一代 CPU 是8位寄存器。不过 8086 可以通过拆分通用寄存器为(AH AL)形式来向下兼容。

能存储的最大数据值:2^16 -1.

指明一个存储位置的地址。8086 CPU 是16位,连着两个字节,先低位后高位。可以存储在16位寄存器中。

汇编指令示例:不区分大小写。

这里注意给 HL 赋值溢出的问题。进制位无法在寄存器中保存。但是也并没有被丢弃,这一点后面再展开讲。

物理地址

内存中的真实地址,不只是逻辑上的了。

8086 内部是16位结构,只能传送16位地址,寻址能力64K。外部则是20位结构,实现方法是两个16位地址合成。16位的段地址和16位的偏移地址经过地址加法器合成。(段地址*16+偏移地址,即段地址左移4位)意思就是20位我们的寄存器存储不下,所以我们用16位段和额外的4位偏移地址表示。

表示方式有多种,比如 2000H 1F60H 或 2100H 0F60H。

算法:段*16+偏移。

指令执行

段地址存储在 CPU 上的四位寄存器中,CS,DS,SS,ES. 即:代码,数据,堆栈,附加。

CS 是代码段寄存器,用于存放指令的段地址,IP 是指令指针寄存器。

IP 相当于偏移码。两者结合取出一条指令中的数据(如 B82301),而后放到指令缓冲器中,再执行。然后 IP+3 跳到下一条指令。

开机后 CS=FFFFH,IP=0000H,cpu 执行 FFFF0H 的指令作为开机后第一个指令。

CS IP 的值的修改不能用一般的方法,如之前学到的 mov 指令。要用专门的转移指令。

转移指令:如 jmp 3:0B46,即 CS=0003,IP=0B46,物理地址=00030+00B46=00B76。

仅修改 IP:jmp 某一合法寄存器,如 jmp AX 就是把 AX 的值放入 IP。

内存自己并没有分段,分段的只是 CPU 逻辑上给内存分的段。

段长度为16倍数,连续。包含若干指令。

CPU 执行段的时候也不关注段怎么划分,它只注重眼前手里的 CS IP 去找对应的指令。

debug 程序

debug 是一个程序,可用于8086模式 debug 或写程序。

win10 不能直接兼容 debug.exe,需要配合 DosBox 使用。

DosBox 每次启动后需要先挂载 asm 文件和 debug.exe 所在的位置,语法:mount c path .可以直接在 option.bat 里配置,使得打开文件时自动启动挂载。

挂载后输入 c: 进入c盘。再输入 debug 运行 debug.exe。

解决win10学习汇编工具的烦恼——汇编Debug的下载和使用(包含可用下载链接)_汇编debug下载_NULL not error的博客-CSDN博客

r:查看或修改某寄存器值。修改:r 寄存器名 ,下一行跟修改数值。

d:查看内存中的内容。

e:以机器指令格式改写内存中内容。但是 ROM 中的数据无法修改,比如 fff0:00 ~ ff 里的生产日期信息,修改后再查看值没变。

b810 里的地址是显存地址,用 e 修改后会直接改变屏幕上的显示。

a:以汇编指令格式写入指令。

a 段地址:偏移地址 输入a指令后逐行输入代码,按两次回车退出。d 段地址:偏移地址 可以查看内存中的指令内容,可以类似 d fff0:0 ff 查看一整段。

d换成u可以翻译为汇编语言查看。

代码执行:先改变CS IP 位置,用r查看当前指针位置,看下一条语句是否是 mov ae,4e20.

然后按下t就执行了当前语句。

例:一个不断*2的程序:

在2000:0 位置写入:

mov ax,1	//地址:20000
add ax,ax	//地址:20003
jmp 2000:3	//地址:20006

执行顺序:ax=1,ax * 2,ax * 2,ax * 2……

内存访数据

依靠数据段地址 ds 和偏移地址。

mov bx,1000H
mov ds,bx	//不能直接送入段寄存器,所以可以用通用寄存器赋值
mov al,[0]	//把ds:0的内存数据读到al里。[]代表偏移地址,这时不用写ds,cpu会自动把数据段地址和偏移地址合起来。

寄存器中数据写入内存就反过来写。

一个内存中的字和段寄存器都是16位的,8086一次也能传送16位。

mov al,[0] 就只把 10000 位置的一个字节放到 al 中。如果是

mov ax,[0] 就是把 10001 10000 两个字节拼成一个字放到 ax 中。

执行程序顺序:先 e 段:偏移 值 为内存赋值,然后 a 段:偏移 程序 写入汇编程序,然后 r 调整 cs ip 指针,t 逐行执行代码。

LIFO。

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

push ax:ax 数据入栈。

pop ax:出栈数据给 ax。

都是以字为单位执行的。

CPU 通过 SS 寄存器的指向,可知这一片内存空间被用作栈。SP 寄存器存储栈顶指针的偏移地址。

如图,数据先存低位再存高位。栈从高位堆到低位,入栈指针-2,出栈+2.

初始栈为空时,sp 在 1000F+1=10010 的位置。存入第一个元素时SP+2,再存入数据。

pop 和 push 相反,先取数据再移动指针。1000C 1000D 里的数据并没有消失,只是改变了索引,类似硬盘格式化。

栈顶和栈底越界是危险的。8086 CPU 并没有保存栈范围的寄存器,无法校验栈的安全范围。CPU 只关心当前栈顶在何处,以及当前要执行的指令是哪一条。

因此我们编程时要自行注意。

因为 push pop 只会改变 sp,因此栈的变化最大范围是0~FFFFH。

例:栈范围10000~1FFFFH,SS=1000H,求空栈时SP的值。

答:栈第一个元素位置:1FFFEH,即SS:1000H,SP:FFFEH.

再出栈:SP+=2,SP=0000H。

硬核二进制安全:汇编语言快速入门底层语言基础

X86 Register:
General-Purpose Register
本文简单介绍了计算机底层基本知识与常用的汇编语言

在这里插入图片描述

16-bit:AX,BX,CX,DX
32-bit:
EAX(Accumulator)累加寄存器
EBX(Base Register)基地址寄存器
ECX(Count Register)计数寄存器
EDX(Data Register)数据寄存器
EBP(Base Pointer)堆栈寄存器
EDI(Index Register)变址寄存器
ESP(Stack Pointer)堆栈顶指针

CS——(Code Segment Register)代码段
DS——(Data Segment Register)数据段
ES——(Extra Segment Register)附加数据段
SS——(Stack Segment Register)堆栈段寄存器
FS——(Extra Segment Register)附加堆栈段寄存器
GS——(Extra Segment Register)附加堆段寄存器
CS:EIP准确定位一个命令

EFLAGS Register:
在这里插入图片描述
在这里插入图片描述
Memory More Work Space:
在这里插入图片描述
movl %eax,%edx edx=eax; register mode 直接寻址
movl $0x123,%edx edx=0x123; immediate 间接寻址
movl (%ebx),%edx edx=(int32_t)ebx; direct
movl (%ebx),%edx edx=(int32_t)ebx; indirect
movl 4(%ebx),%ebx edx=*(int32_t)(ebx+4); displaced
Stack Memory Operation
在这里插入图片描述

How to execute Push command in stack
Push:

pushl %eax 
subl $4,%esp #开辟一个virtual varibal memory

POP:

popl %eax 
movl (%esp),%eax
addl $4,%esp

pushl %8
movl %esp,%ebp
;%ebp=%esp
subl $4,%esp
;%esp = $4 %ebp=%4
movl $8,(%esp)
%(esp)=$8

在这里插入图片描述

enter:
pushl %ebp
movl %esp,%ebp
leave
movl %ebp,%esp
popl %ebp

如何把c程序编译成汇编

gcc -s -o test.s test.c 

2021/6/11

以上是关于汇编语言_1 计算机基础;寄存器的主要内容,如果未能解决你的问题,请参考以下文章

7.11 计算机基础

python学习_多进程

汇编学习_1.CPU外部通讯基础

计算机基础和Linux基础

计算机基础之——计算机硬件

第一章python基础-1