一些东西
指令执行周期
取指令,译码,执行
加载执行程序
1 |
|
32位x86处理器
1 |
|
64位x86处理器
1 |
|
1 |
|
I/O访问层次
1 |
|
汇编语言基本元素
1 |
|
定义数据类型
1 |
|
数据传送指令:
1 |
|
加法与减法
1 |
|
数据相关的运算符和伪指令
1 |
|
间接寻址
1 |
|
JMP和LOOP
1 |
|
堆栈操作
1 |
|
定义函数
1 |
|
布尔与比较指令
1 |
|
条件跳转指令
JCC指令 | 解释 | 英文原文 | 检查符号位 | 应用 |
---|---|---|---|---|
JZ | 如果为0则跳转 | jump if zero | ZF = 1 | if(i == 0) |
JE | 如果相等则跳转 | jump if equal | ZF = 1 | if(i == j) |
JNZ | 若为0则不跳转 | jump if not zero | ZF = 0 | if(i != 0) |
JNE | 若不相等则跳转 | jump if not equal | ZF = 0 | if(i != j) |
JS | 若为负数则跳转 | jump if sign | SF = 1 | if(i < 0) |
JNS | 若不为负数则跳转 | jump if not sign | SF = 0 | if (i > 0) |
JP/JPE | 若1出现的次数为偶数跳转 | jump if parity(even) | PF = 1 | |
JNP/JPO | 若1出现的次数为奇数跳转 | jump if not party(odd) | PF = 0 | |
JO | 若溢出则为0 | jump if overflow | OF = 1 | |
JNO | 若无溢出则跳转 | jump if not overflow | OF = 0 | |
JC | 若进位则跳转 | jump if carry | CF =1 | if(i < j) |
JB | 若低于则跳转 | jump if below | CF = 1 | if(i < j) |
JNAE | 若不高于等于则跳转 | jump if not above equal | CF = 1 | if (i < j) |
JNC | 若无进位则跳转 | jump if not carry | CF = 0 | if(i > =j ) |
JNB | 若不小于则跳转 | jump if not below | CF = 0 | if(i >= j) |
JAE | 若高于等于则跳转 | jump if above equal | CF = 0 | if(i >= j ) |
JBE | 若小于等于则跳转 | jump if above equal | CF = 1或 ZF = 1 | if(i <= j) |
JNA | 若不超过则跳转 | jump if not above | CF = 1或ZF =1 | if(i <=j) |
JNBE | 若不小于相等则跳转 | jump if not below equal | ||
JA | ||||
JL | ||||
JNGE | ||||
JNL | ||||
JGE | ||||
JLE | ||||
JNG | ||||
JNL | ||||
JG | ||||
JCC指令 中文含义 英文原意 检查符号位 典型C应用
JZ/JE 若为0则跳转;若相等则跳转 jump if zero;jump if equal ZF=1 if (i == j);if (i == 0);
JNZ/JNE 若不为0则跳转;若不相等则跳转 jump if not zero;jump if not equal ZF=0 if (i != j);if (i != 0);
JS 若为负则跳转 jump if sign SF=1 if (i < 0);
JNS 若为正则跳转 jump if not sign SF=0 if (i > 0);
JP/JPE 若1出现次数为偶数则跳转 jump if Parity (Even) PF=1 (null)
JNP/JPO 若1出现次数为奇数则跳转 jump if not parity (odd) PF=0 (null)
JO 若溢出则跳转 jump if overflow OF=1 (null)
JNO 若无溢出则跳转 jump if not overflow OF=0 (null)
JC/JB/JNAE 若进位则跳转;若低于则跳转;若不高于等于则跳转 jump if carry;jump if below;jump if not above equal CF=1 if (i < j);
JNC/JNB/JAE 若无进位则跳转;若不低于则跳转;若高于等于则跳转; jump if not carry;jump if not below;jump if above equal CF=0 if (i >= j);
JBE/JNA 若低于等于则跳转;若不高于则跳转 jump if below equal;jump if not above ZF=1或CF=1 if (i <= j);
JNBE/JA 若不低于等于则跳转;若高于则跳转 jump if not below equal;jump if above ZF=0或CF=0 if (i > j);
JL/JNGE 若小于则跳转;若不大于等于则跳转 jump if less;jump if not greater equal SF != OF if (si < sj);
JNL/JGE 若不小于则跳转;若大于等于则跳转; jump if not less;jump if greater equal SF = OF if (si >= sj);
JLE/JNG 若小于等于则跳转;若不大于则跳转 jump if less equal;jump if not greater ZF != OF 或 ZF=1 if (si <= sj);
JNLE/JG 若不小于等于则跳转;若大于则跳转 jump if not less equal;jump if greater SF=0F 且 ZF=0 if(si>sj)
1
函数调用约定
是函数调用者和被调用的函数体之间关于参数传递、返回值传递、堆栈清除、寄存器使用的一种约定。
声明语法为:
1 |
|
cdecl–C Declaration的缩写,C语言缺省的调用约定
cdecl调用约定意味着:
- 参数从右向左压入堆栈
- 调用者负责清理堆栈
- C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大特色。
- 仅在函数名前加上一个下划线前缀,格式为_functionname。
声明语法为:
1 |
|
stdcall(pascal)–Standard Call的缩写,C++的标准调用方式
在Microsoft C++系列的C/C++编译器中,常常用PASCAL宏来声明这个调用约定,类似的宏还有WINAPI和CALLBACK。
一般WIN32的函数都是__stdcallstdcall的调用约定意味着:
- 参数从右向左压入堆栈
- 函数自身清理堆栈
- 函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸
声明语法为:
1 |
|
fastcall调用约定意味着:
- 函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈
- 函数自身清理堆栈
- 函数名修改规则同stdcall:函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸
thiscall一C++类成员缺省的调用约定
thiscall是唯一一个不能明确指明的函数修饰,因为thiscall不是关键字。由于成员函数调用还有一个this指针,因此必须特殊处理,thiscall意味着:
参数从右向左入栈
如果参数个数不确定,this指针在所有参数压栈后被压入堆栈。如果参数个数确定,this指针通过ecx传递给被调用者。
如果参数个数不确定,调用者清理堆栈,否则函数自己清理堆栈
对于参数个数不定的情况下,类似cdecl,固定时类似于stdcall,
以“?”标识函数名的开始,后跟函数名;
函数名后面以“@@YG”标识参数表的开始,后跟参数表;
参数表以代号表示:
X–void ,
D–char,
E–unsigned char,
F–short,
H–int,
I–unsigned int,
J–long,
K–unsigned long,
M–float,
N–double,
_N–bool,
PA–表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复…
参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;
参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。
例如:
1 |
|
- __cdecl调用约定:_
规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YA”。
- __fastcall调用约定:_
规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YI”。
- 函数调用约定导致的常见问题
如果定义的约定和使用的约定不一致,则将导致堆栈被破坏,导致严重问题,下面是两种常见的问题:
1.函数原型声明和函数体定义不一致
2.DLL导入函数时声明了不同的函数约定
调用函数的代码和被调函数必须采用相同的函数的调用约定,程序才能正常运行。
x32是x86架构的32位拓展,向后兼容于16位的x86架构。计算机的CPU一次最多能处理32位数据。,当然32位计算机通常也可以处理16位和8位数据。
x64是x86架构的64位拓展,向后兼容于16位及32位的x86架构。x64于1999年由AMD设计,AMD首次公开64位集以扩展给x86,称为“AMD64”。其后也为英特尔所采用。
x86是一个intel通用计算机系列的标准编号缩写,也标识一套通用的计算机指令集合,X与处理器没有任何关系,它是一个对所有*86系统的简单的通配符定义。
//x96dbg是安装x32dbg和x64dbg用的
各种数据类型字节数
伪指令又称为伪操作,它是在对源程序汇编期间由汇编程序处理的操作,它们可以完成如处理器选择、定义程序模式、定义数据、分配存储区、指示程序结束等功能。
博客相关
图片大小
1 |
|
表格:
1 |
|
hexo博客不更新,把.deploy_git文件夹删除,再hexo g -d
作业,程序,进程和线程
进程
一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。
线程
进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。
作业:
作业指用户在一次解决或是一个事务处理过程中要求计算机系统所做的工作的集合。作业由三部分组成,即程序、数据和作业说明书。一个作业可以包含多个程序和多个数据集。作业说明书在系统中生成一个称为作业控制块(job control block,JCB)的表格。该表格登记该作业所要求的资源情况、预计执行时间和执行优先级等。从而,操作系统通过该表了解到作业要求,并分配资源和控制作业中程序和数据的编译、链接、装入和执行等。
作业是由一系列有序的步骤组成的。作业的完成要经过作业提交、作业收容、作业执行和作业完成4个阶段。在执行一个作业可能会运行多个不同的进程。
需要说明的是,作业的概念主要用在批处理系统中,而且,在批处理系统中,作业是抢占内存的基本单位。也就是说,批处理系统以作业为单位把程序和数据调入内存以便执行。
程序:
程序是一组有序指令的集合,并存放于某种介质中,是一个静态概念。
进程:
进程是为使程序能并发执行,且为了对并发执行的程序加以描述和控制而引入的概念。
在了解进程前,先说明下进程实体。进程实体是由程序段、相关的数据段和PCB三部分组成,是一个能独立运行、独立分配资源和独立接受调动的基本单位。
现在来说明进程的定义:进程是进程实体的一次执行过程,是系统进行资源分配和调度的一个独立单位。它是一个动态概念。
线程:
随着多处理机系统的发展,提高程序的并发执行程度的要求越来越高。为提高系统的并发执行度,进而引入了线程的概念。线程是比进程更小的能独立运行的基本单位(故又称“轻型进程”),更好的提高了程序的并发执行程度充分发挥了多处理机的优势。
RAM是随机存取存储器(random access memory),是计算机内部存储器中的一种,也是其中最重要的,计算机和手机中一般把其叫做(运行)内存,它的速度要比硬盘快得多,所以用运行程序在RAM中,而存放运行时不用的数据则在硬盘中,什么时候需要数据,便把数据从硬盘中拿到内存,但同时RAM断电会丢失数据,所以我们电脑如果断电了就会丢失原来正在运行的数据。所以,手机中的RAM和电脑中的RAM的概念是相同的,RAM即内存越大,能同时在内存中执行的程序就越多,性能一般是越好的。
ROM是只读存储器(Read-Only Memory),也是计算机内部存储器中的一种,而硬盘是外部存储器,所以对于大学学子来说,考试时你如果把这两个混为一种东西绝对是错误的,当然,如果出选择题让你选,那么BIOS应该是用到ROM的那个。那么ROM究竟是干什么的,ROM和硬盘是否就没有任何关系呢?这就要从其发展历程说起,早期,乃至现在,我们的主要存储介质都是磁性存储,也就是磁盘,分为硬盘和软盘,硬盘不太适合做移动存储,因为其磁头容易损坏,不耐摔,而且体积较大,就算是缩小容量仍然很难缩小其体积,软盘虽然用作移动介质还算方便,但软盘容量过于小,不够用,而光盘虽然容量大但不易擦写,同时体积也不够小,这时就很适合使用半导体存储介质——ROM和RAM,ROM用来嵌入电脑主板或者做移动存储介质就很合适了,其体积够小,提供的容量可以比光盘和软盘的大,速度也更快,但成本相对更高,而且早期的ROM因为技术不成熟所以无法擦写,出厂后就只能读数据,所以叫只读存储器,后来随着技术的发展,在ROM的基础上出现了新的半导体存储介质EPROM和EEPROM,这两种可擦写,这就不符合ROM的命名,但是由于是在ROM的技术上衍变出来的,所以延用了一部分原来的叫法,此时非易失的半导体存储介质开始得以广泛应用,被大量用于电脑主板的bios和嵌入式存储,而后来在这两种技术的发展上又发展出了NAND FLASH闪存,这就是我们现在用的U盘中用到的技术,同样,因为其体积小,容量和速度均不错,现在手机存储中的emmc颗粒也是用的这种技术,所以有手机厂商就把手机的存储容量约定俗成为ROM,其继承ROM断电不丢失数据的特性,而且有着较快的速度。
那么电脑硬盘和ROM有什么关系呢?由于ROM和硬盘都可以存储数据而且断电不会丢失,而有都广泛运用于电子产品中,所以有人就对两者产生了混淆。硬盘分为两种,一种是机械硬盘(即磁盘HDD),一种是固态硬盘(SSD),磁盘和ROM没什么关系,但是固态硬盘就不一样了,固态硬盘用到的颗粒也是基于NAND FLASH技术,和u盘以及手机存储有点相似,所以说硬盘和ROM还是有关系的,固态硬盘的存储颗粒是ROM技术发展的产物,但不能说ROM就是硬盘。
编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程序。一个现代编译器的主要工作流程:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 链接器 (Linker) → 可执行程序 (executables)