首页 > 其他分享 >sadadasda

sadadasda

时间:2022-11-16 11:14:30浏览次数:33  
标签:IP 程序 mov 指令 内存 CPU sadadasda

你好啊

目录

基础知识

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

CPU(Central Processing Unit)中央处理单元

汇编语言是机器语言的助记符(伪代码)

image-20221105172755668

汇编语言发展至今,有以下 3 类指令组成。
(1)汇编指令:机器码的助记符,有对应的机器码。
(2)伪指令:没有对应的机器码,由编译器执行,计算机并不执行。
(3) 其他符号:如+、-、*、/等,由编译器识别,没有对应的机器码。
汇编语言的核心是汇编指令,它决定了汇编语言的特性。

寄存器

一个 16 进制位=4 个二进制位,,,,4H=0100B

两个 16 进制位=8 个二进制位=1 个字节

通用寄存器 AX(AH+AL),BX(BH+BL),CX(CH+CL),DX(DH+DL)

段寄存器 CS,DS,SS,ES

mov x,y

add x,y

十六位结构的 CPU:

运算器一次最多可以处理 16 位的数据;
寄存器的最大宽度为 16 位;
寄存器和运算器之间的通路为 16 位。

段地址 x16+偏移地址=物理地址的本质含义是: CPU 在访问内存时,用一个基础地址(段地址 x16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。

内存没有段的概念,段的划分来自 CPU,CPU 根据自己的段找到物理地址

8086CPU 的工作过程:

(1)从 CS:IP 指向的内存单元读取指令,读取的指令进入指令缓冲器;
(2)IP=IP+所读取指令的长度,从而指向下一条指令;
(3)执行指令。转到步骤(1),重复这个过程。


在 8086CPU. 加电启动或复位后(即 CPU 刚开始工作时)CS 和 IP 被设置为 CS =FFFFH, IP=0000H, 即在 8086PC 机刚启动时,CPU 从内存 FFFF0H 单元中读取指令执行,FFFF0H 单元中的指令是 8086PC 机开机后执行的第一条指令。(BIOS)

CS:IP 同时修改:jmp 段地址:偏移地址
仅修改 IP:jmp 合法寄存器||用寄存器中的值修改 IP

8086 机中任意时刻,CPU 将 CS:IP 指向的内容当做指令执行

代码段:将一组内存单元定义为一个段,可以将长度为 N(N<=64KB)的一组代码,存在一组地址连续、起始地址为 16 的倍数的内存单元中

>内存中字的存储

8086CPU 是小端法,16 位机,所以 4E20H

将起始地址为 N 的字单元简称为 N 地址字单元

0 地址单元存储字节型数据是 20H,0 地址单元存储的字型数据是 4E20H

image-20221112101121845
img
imgasda

>DS 和[address]


将10000H读入al中
mov ax,1000H
mov ds,ax
mov al,[0]

//mov ds,1000H  ×,这对于DS来说是非法指令[设计缺陷]
需要找“媒人”

CS:IP 指向代码段

-a 更改代码

代码对数据段 DS 所指的内存单元进行操作

>mov add sub 指令

mov ax,6
mov bx,ax
mov ax,[0]
mov [0],ax
mov dx,ax
mov ax,ds
mov ds,[0]

image-20221112150338223image-20221112150308615

段地址不能用于算术运算,add、sub 不行

>数据段

注意注意

AL 内存字节,AX 内存字

0001:0000 和 0000:0010 是等价的,0001:0001 和 0000:0011 等价,注意换算

>栈

现今的 CPU 都有栈的设计

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

pop ax:将栈顶的数据送入 ax

栈的出栈和入栈操作都是以为单位的===>SP+2

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

image-20221112154536680

image-20221112154546469

如果将 10000H~1000FH 当做栈,初始栈的状态为空,SP=0010H,栈内一个元素,SP=00Eh,栈满 SP=0000H

硬盘格式化,数据还存在,只是改变了标签,指针(栈)

C 语言中局部变量,在函数之外的局部变量没有效果(栈)

栈顶超界问题

栈溢出(攻击方式)

CPU 不清楚栈的上界和下界在哪里

8086CPU 的工作机理,只考虑当前的情况:

当前栈顶在何处,当前要执行的指令是那一条
栈(C 语言自动分配)堆(线性表,必须释放)

栈空间当然也是内存空间的一部分,它只是一段可以以一种特殊的方式进行访问的内存空间。

image-20221112162433077

image-20221112162452921

后进先出:所以恢复寄存器内容的时候要先恢复后进的,寄存器入栈和出栈的顺序要相反

系统喜欢 XOR(异或)进行清零操作

image-20221112163922780

push、pop 实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与 mov 指令不同的是,push 和 pop 指令访问的内存单元的地址不是在指令中给出的,而是由 SS:SP 指出的。

同时 push 和 pop 还要改变 SP

push、pop 等栈操作指令,修改的只是 SP,也就是说,栈顶的变化范围最大为:0~FFFFH。

将一段内存当作栈段,仅仅是我们在编程时的一种安排,CPU 并不会由于这种安排,就在执行 push、pop 等栈操作指令时就自动地将我们定义的栈段当作栈空间来访问。

10000H~1FFFFH 当做栈段,当栈为空时 SP 指向 0000H

一个栈段最大可设为多少?16 位 CPU,FFFFH,即为 2^16,64KB,栈空时 SP=0,不空不满 0<SP<FFFFH,栈满时 SP=0

堆栈的作用:

早期的 C 语言,保存函数的返回地址,调用函数时把寄存器的值都存放在栈里面

为了函数,面对过程而存在

代码段:CS:IP 数据段 DS 栈段:SS:SP

段是人为定义的,对于 CPU 来说都一样,只是执行的位置(指针)不同

一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么也不
是。关键在于 CPU 中寄存器的设置,即 CS、IP, SS, SP, DS 的指向。

第一个程序

>一个源程序从写出到执行的过程

伪指令被 CPU 所执行

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

汇编语言由多个段组成(至少有一个段)

汇编编源程序:
伪指令(编译器处理)
汇编指令( 编译为机器码)
程序:源程序中最终由计算机执行、处理的指令或数据。

程序(指令和数据)最先以汇编指令的形式存在源程序中,经编译、连接后转变为机器码,存储在可执行文件中。

assume CS:codesg(伪指令,编译时由编译器执行)
XXX segment

XXX ends//end segment
end//指令结束,释放内存??

>源程序>编辑源程序>编译>连接>以简化的方式进行编译和连接>.exe 的执行

DOS 是个单任务操作系统

一个程序 P2 在一个可执行文件中,P2 要运行,必须有一个正在运行的程序 P1,将 P2 从可执行文件中加载入内存后,将 CPU 的控制权交给 P2,P2 才能运行(P1 暂停运行)P2 运行完,CPU 控制权交给 P1

一个程序结束后,将 CPU 的控制权交还给使它得以运行的程序===>>程序返回

程序返回:(汇编指令,由 CPU 执行)

​ mov ax,4c00H

​ int 21H

逻辑错误:程序编译时不能表现出来的、在运行时发生的错误

连接的作用有以下几个:
当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序将它们连接到一起,生成一个可执行文件;

​ 程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件;

一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这此内容处理为最终的可执行信息。所以,在只有一个源程序文件,而又不需要调用某个库中的子程序的情况下,也必项用连接程序对目标文件进行处理,生成可执行文件。

>可执行文件中的程序装入内存并运行的原理

正在运行的 command(shell),将 1.exe 中的程序加载入内存

command 设置 CPU 的 CS:IP 指向程序的第一条指令(程序的入口),从而使程序得以运行

程序运行结束,返回到 command,CPU 继续运行 command

>程序执行过程的跟踪

Debug 将程序加载入内存,设置 CS:IP 指向程序的入口,但是 Debug 不放弃对 CPU 的控制,所以可以使用 debug 的命令进行调试

image-20221114212058706

第三步:SA:0 和 SA+10H:0,而不是 SA:100H 是因为这种表述是在描述不同的段

psp 重定位, 程序的接口

程序加载后,ds 中存放着程序所在内存区的段地址,这个内存区的偏移地址为 0,则程序所在的内存区的地址为: ds:0 ;

这个内存区的前 256 个字节中存放的是 PSP,dos 用来和程序进行通信。

从 256 字节处向后的空间存放的是程序。

--------------------------------------总结-------------------------------------------

​ 在内存管理中,与栈对应是堆。

​ 对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;

​ 对于栈来讲,它的生长方式是向下的,是向着内存地址减小的方向增长。

​ 在内存中,“堆”和“栈”共用全部的自由空间,只不过各自的起始地址和增长方向不同,它们之间并没有一个固定的界限,如果在运行时,“堆”和 “栈”增长到发生了相互覆盖时,称为“栈堆冲突”,系统肯定垮台。

[BX]和 loop 指令

在 debug 之中写程序,-a 修改的[0][1]等偏移地址,是可行的

但是在 masm 写的程序中,是不可行的,会被当做 01 看待

>[BX]

>Loop 指令

包含多个段的程序

更灵活的定位内存地址的方法

数据处理的两个基本问题

转移指令的原理

CALL 和 RET 指令

标志寄存器

内中断

int 指令

端口

外中断

直接定址表

使用 BIOS 进行键盘输入和磁盘读写

实验

操作指令:

R:查看改变 CPU 寄存器的值,R CS,R

D:查看内存中的内容,d 1000:0,d 1000:0 9

e:改写内存中的内容,e 1000:0 0 1 2 3 4,e 1000:10 .....(写机器码)

e 命令写入机器码,u 命令查看内存中机器码的含义,t 命令执行 CS:IP 指向的机器码

a:以汇编形式在内存中写入机器指令,a 1000:0 mov ax,1.....(写汇编指令)

问题与解决

大端法和小端法压栈有什么不同

学习资源

标签:IP,程序,mov,指令,内存,CPU,sadadasda
From: https://www.cnblogs.com/zhangermazi/p/16895166.html

相关文章