操作系统学习2 x86寄存器、汇编伪指令与程序调试 |
您所在的位置:网站首页 › 汇编语言指令指针寄存器及标志寄存器 › 操作系统学习2 x86寄存器、汇编伪指令与程序调试 |
操作系统学习2 x86寄存器、汇编伪指令与程序调试
一、一些基本概念二、8086的寄存器1. 通用寄存器2. 段寄存器3. 索引寄存器4. 指针寄存器5. 指令指针寄存器6. 标志寄存器PSW
三、常用的汇编指令四、一些汇编伪指令1. 段定义 segment2. 汇编结束3. 假设 assume4. 寻址方式
五、使用DosBox和Debug工具一段代码示例(1) 新建一个1.asm文件:(2) 启动DosBox挂载本地磁盘(3) 编译(4) debug加载(5) 使用指令查看
六、使用OllyDbg反汇编和跟踪程序
一、一些基本概念
比特(bit):二进制的一位字节(byte):8比特的数据字(word):2个字节长度
二、8086的寄存器
寄存器是CPU内部高速存取数据的地方,比缓存更接近CPU的运算器。 8086是16位cpu(字长16位): 其CPU一次最多可处理16位数据寄存器最大宽度位16位寄存器与PU之间的通路位16位。地址20位,最大可寻址 2 20 = 1 M B 2^{20}=1MB 220=1MB 内存空间。这些寄存器大致分三种: 通用寄存器:AX BX CX DX,每个寄存器又可以分为AH AL高8位和低8位分别使用;段寄存器:CS DS SS ES;特殊用途寄存器:(如 IP、SP、BP、SI、DI 等)。 1. 通用寄存器8086有14个寄存器:AX BX CX DX SI DI SP BP IP CS SS DS ES PSW。 AX:累加器寄存器(Accumulator Register),用于算术运算和数据传输。可以分为两个独立的8位寄存器:AH(高位)和AL(低位)。BX:基址寄存器(Base Register),通常用作内存偏移地址的基址。CX:计数器寄存器(Counter Register),通常用于循环计数或者重复指令执行。DX:数据寄存器(Data Register),通常用于I/O操作和数据传输。 2. 段寄存器 CS:代码段寄存器(Code Segment Register),用于存储当前指令的段地址。IP:指令指针寄存器(Instruction Pointer Register),用于存储下一条要执行的指令的地址。CPU读取指令的寻址=CS*16+IP,即从CS:IP处执行指令。读取指令后,IP值会自动增加指向下一条指令。 DS:数据段寄存器(Data Segment Register),存放数据的段地址。注意8086不支持对段寄存器直接赋值,需要用另一个通用寄存器赋值给它。SS:堆栈段寄存器(Stack Segment Register),存放栈顶的段地址SP:栈顶的偏移地址。 SS:SP指向栈顶元素。 8086入栈时从高地址向低地址增长,出栈后,SS:SP指向新的栈顶。BP:基址指针寄存器(Base Pointer Register),在过程调用和访问堆栈中的局部变量时使用。ES:附加段寄存器(Extra Segment Register),在一些特殊情况下用于存储额外的数据段地址。 3. 索引寄存器 SI:源索引寄存器(Source Index Register),在字符串操作中通常用于指向源数据。DI:目的索引寄存器(Destination Index Register),在字符串操作中通常用于指向目标数据。 一段内存是放代码、数据还是栈,取决非于这几个段寄存器的设置。 4. 指针寄存器SP:堆栈指针寄存器(Stack Pointer Register),用于指向堆栈顶部。 BP:基址指针寄存器(Base Pointer Register),在过程调用和访问堆栈中的局部变量时使用。 5. 指令指针寄存器IP:指令指针寄存器(Instruction Pointer Register),用于存储下一条要执行的指令的地址。 6. 标志寄存器PSW 1514131211109876543210OFDFIFTFSFZFAFPFCF OF:有符号数运算溢出标志DF:在串处理指令中,控制每次操作后si、di的增减。df=0每次操作后递增,df=1每次操作后递减。SF:相关指令执行后,其结果是否为负。为负则sf=1;否则sf=0。ZF:相关指令执行后,其结果是否为0。为0则zf=1;否则zf=0。PF:相关指令执行后,其结果的所有bit位中1的个数是否为偶数。为偶数则pf=1;否则pf=0。CF:在无符号数运算时,运算结果的最高有效位是否向更高位进位或从更高位借位。是则cf=1;否则cf=0。 三、常用的汇编指令 指令格式作用movmov dest, srcdest = srcaddadd dest, srcdest = dest + srcadcadc dest, srcdest = dest + src + CFsubsub dest, srcdest = dest - srcsbbsbb dest, srcdest = dest - src - CFpushpush src入栈(改变SP后写内存)poppop src出栈(读内存后改变SP)pushfpushf将标志寄存器的值压栈popfpopf从栈中弹出数据送入标志寄存器中andand dest, srcdest = dest & srcoror dest, srcdest = destshlshl dest, 位数dest左移指定位数,位数大于1时必须放在cl中shrshr dest, 位数dest右移指定位数,位数大于1时必须放在cl中inin al/ax, 端口号从端口读入数据outout 端口号, al/ax发送数据到端口mulmul reg/内存单元乘法divdiv reg/内存单元除法cmpcmp dest, src比较转移指令见下控制CPU执行指定内存的指令串传送指令见下见下intint 中断类型码引发中断过程 四、一些汇编伪指令汇编指令是CPU认识的对应2进制的指令,而伪指令是给编译器看的。 1. 段定义 segment 段名 segment ... 段名 ends 2. 汇编结束 end 3. 假设 assumeassume 指令用于建立一个段寄存器与一个段名之间的关联,以便在程序中使用简化的段地址访问数据和指令。 assume cs:codesg ; 假设代码寄存器和下面定义的codesg相关联 codesg segment ; 标志代码段开始 ... codesg ends ; 代码段结束 endassume cs:codesg 指令建立了代码段寄存器 cs 与 codesg 段名之间的关联。这意味着在程序的后续部分,可以使用 cs 寄存器来访问 codesg 段中的指令和数据。 4. 寻址方式 ()表示一个寄存器或者一个内存单元中的内容。EA表示偏移地址。SA表示段地址。idata表示常量。 五、使用DosBox和Debug工具64位操作系统无法直接使用Debug.exe工具了,需要安装一个DosBox,然后进行下面操作: 挂载本地磁盘,命令mount c: 本地文件夹把debug.exe masm.exe和要调试的程序放到本地文件夹然后就可以使用debug命令了。常用的debug命令: R :查看更改cpu寄存器内容D:查看内存中内容E:改写内存中内容U:将内存中机器指令翻译成汇编指令T:执行一条机器指令A:以汇编格式在内存中写入一条指令 一段代码示例 (1) 新建一个1.asm文件: code segment assume cs:code s:mov ax,0025h mov cl,2 shl ax,cl mov ax,4ch int 21h code ends end s (2) 启动DosBox挂载本地磁盘 mount c: d:/Documents/asm这时生成1.exe (4) debug加载 c: debug 1.exe (5) 使用指令查看 uOllyDbg通常称作OD,是反汇编工作的常用工具。 下载地址:http://www.ollydbg.de/ 启动后,可以加载上篇编译的Hello.exe程序: 这里可以设置断点、跟踪程序,右侧还有一些寄存器的值可以查看。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |