X86汇编指令

8086CPU地址总线宽度为20, 也就是说一个内存物理地址是5位,内存地址空间为1Mb;数据总线为16位;寄存器为16位。

16位结构的CPU包括以下特性:

1,运算符最多处理16位数据。

2,寄存器最大宽度为16位。

3,寄存器与运算器之间的通路是16位。

这里就出现了一个问题,如果由16位推出20位的物理地址呢?

所以就出现了段的概念:

一个物理地址由段地址和偏移地址构成,即物理地址=段地址*16 + 偏移地址

也可以说段地址左移4位,然后我们可以推出偏移地址最大为2的16次方,即16Kb.

这里我们要强调一个概念:

CPU是死的,一点都不智能,对于它本身而言,并不知道什么段的概念,段只是用来让我们编程者使用的,我们可以自己定义一个段的开始(定义CS或者DS),然后利用偏移地址灵活执行我们写的指令,这样我们就可以避免指令在内存空间的互相掩盖。

8086CPU不支持将一个数据直接写到段寄存器中去。

8086的栈操作是以字为单位的,这里我们还是要强调一个概念:

CPU是死的,它才不知道栈的概念呢,栈是我们编程者自己在数据段里开辟,然后我们用pop,push汇编指令操作,一切都是我们编程者操作出来的。

CPU是如何知道栈的地址呢?:

CPU才不会知道呢,是我们编程者自己首先定义好了一个栈段,然后我们将这个栈段地址赋值到SS栈段寄存器中去,同时初始化SP寄存器。这样以后我们pop或者push一个字时,sp加2或者减2。还是那句话,都是我们编程者实现栈的功能,让SS和SP永远指向栈顶。

只有bx,si,di,bp这四个寄存器可以进行内存单元寻址的,即[bx]这样语法操作的,其中bx,bp这两个寄存器不能同时出现,如[bx,bi],还有si,di这两个寄存器也是不能同时出现的。

bp寄存器隐形的段地址是ss。如我们这样操作[ba],那么是通过SS段地址寻址内存单元的。

寄存器寻址几种方式:

1,直接寻址:[idata]    idata 为立即数

2,寄存器间接寻址: [bx] , 默认段地址是DS

3,寄存器相对寻址:[bx+idata] ,默认段地址是DS

4,基址变址寻址:[bx+si], 默认段地址DS

5,相对基址变址寻址:[bx+si+idata], SA是DS

指令要处理的数据长度问题:

对于这个问题,我们要根据编程者自己的选择的编译器而定,像我们在windows下用的都是Masm风格的汇编编程,在linux上则是使用AT&T风格的。

这里是就masm风格而言,当我们操作一个寄存器时,我们根据寄存器的长度来确定数据的长度,比如:

mov ax, [0]; 这里我们就是要操作的数据长度是16位的。

但是当没有寄存器的时候,我们就要通过标记符来确定了。格式如下:

操作符 X ptr data, data; 这里X ptr依据(X可以使word或者byte)来指定操作数据长度。

像push和pop就不需要指定了,他们两默认的是一个字。

div除法指令:被除数一般默认在AX或者BX中,或者就是32位的存储在AX,BX中,然后除完之后,余数在DX中,商在AX中

伪指令:

db:定义一个字节

dw:定义一个字

dd:double defined word 定义两个字节

dup:与db,dw,dd配合使用,表示复制的意思,比如: db 3 dup(0);

转移指令:

修改CS,IP或者仅仅修改IP的指令统称为转移指令,比如:

jmp data,只修改ip

jmp SA:EA 修改cs和IP

offset操作符:

获取一个标号的偏移地址,比如:

start:

mov ....

s:

mov ax, offset s;   此时相当于(mov ax, 1)

jmp指令:

jmp idata; jmp sa:ea; jmp short 标号(在段内短跳转);jmp far ptr 标号(段间跳转);jmp reg; jmp word ptr 内存单元地址(这里是将那个内存单元里的值给IP,段内转移); jmp dword ptr 内存单元地址(段间跳转,以内存单元地址所存的两个字的高地址为段地址,低地址为偏移地址);

jcxz指令:

当cx=0 跳转

loop指令:

相当于执行cx自减一,并前cx不等于0就跳转,跳转位移是8位,也就是说偏移地址在-128~127之间。

ret 指令:

有两条指令:ret,retf指令

ret指令相当于pop IP

retf    相当于连续执行    pop IP; pop CS 两条指令

call指令:

格式如下:

call 标号;    将当前IP压栈,然后跳到标号处执行(改变IP值)

call far ptr 标号;    段间转移

call reg(16位);    跳到IP=寄存器中的内容

call word ptr 内存单元地址;    跳到内存单元给定的值

call dword ptr 内存单元地址;  相当于执行:push CS; push IP; jmp dword ptr 内存单元地址;

call 和 ret一般配合使用,相当于调用了一个子函数。

mul乘法指令:

和div一样,用到AX,DX寄存器

标志寄存器:

里面存储的信息可以称为PSW(程序状态字),包括这些状态:

第六位,ZF:标明执行结果是否为0;

第二位, PF:奇偶标志位:执行结果中如果1的个数为偶数的话,则置1

第七位,SF:符号标志位:结果为负数则为1

第零位,CF:进位借位标志符:当最高有效位需要像更高位进位或者借位则置1(对于无符号位数)

第十一位,OF:溢出标志位(对于有符号位数)

第十位:DF:方向标志位:在串处理中,控制每次si,di的增减。DF为0,则每次si,di递减

串传送指令:

movsb;

相当于执行如下指令:mov es:[di], byte ptr ds:[si]; 如果DF=0 ,则后续为:inc si; inc di;

如果DF=1,则后续为: dec si; dec di;

movsw;

每次传送的是一个字

一般我们传送一个串的话选择这样的命令:

rep movsb;

相当于:

s: movsb;

loop s;  依据CX来判断

pushf; popf;  将标志寄存器压栈或者弹出

条件转移指令:

je: equal,如果等于了,则ZF=0,依ZF作为判断                     jne:   no equal

jb: below,如果第一个数小于第二个数,则CF=1                     jnb; no below

ja: above                                                                              jna:

时间: 2024-10-10 08:49:01

X86汇编指令的相关文章

<<ASM>> x86汇编指令浅析

学习研究系统/软件底层机制的朋友,汇编是必修课之一.由于汇编具有低级语言固有的特性,使得前期的学习掌握异常困难.本文将着重介绍一些常用而又关键的汇编指令,借此提携那些还在苦苦攀援的“初学者”们. 目前市场上主流的汇编教材中,王爽所著的<汇编语言(第二版)>比较受读者的青睐.笔者自学汇编所选的汇编教材则是杨继文所著的<80x86汇编语言程序设计教程>和<汇编语言程序设计——从DOS到Windows>张雪兰/谭毓安:根据书的厚度就可知其难易程度.读者若初次接触汇编,可以考虑

x86汇编指令详解

80x86指令系统 80x86指令系统,指令按功能可分为以下七个部分. (1) 数据传送指令. (2) 算术运算指令. (3) 逻辑运算指令. (4) 串操作指令. (5) 控制转移指令. (6) 处理器控制指令. (7) 保护方式指令. 3.3.1数据传送指令 数据传送指令包括:通用数据传送指令.地址传送指令.标志寄存器传送指令.符号扩展指令.扩展传送指令等. 一.通用数据传送指令 1传送指令 传送指令是使用最频繁的指令,格式:MOV DEST,SRC 功能:把一个字节,字或双字从源操作数S

x86汇编指令具体解释

80x86指令系统 80x86指令系统,指令按功能可分为下面七个部分. (1) 数据传送指令. (2) 算术运算指令. (3) 逻辑运算指令. (4) 串操作指令. (5) 控制转移指令. (6) 处理器控制指令. (7) 保护方式指令. 3.3.1数据传送指令 数据传送指令包含:通用数据传送指令.地址传送指令.标志寄存器传送指令.符号扩展指令.扩展传送指令等. 一.通用数据传送指令 1传送指令 传送指令是使用最频繁的指令,格式:MOV DEST,SRC 功能:把一个字节,字或双字从源操作数S

现代32位或64位x86汇编

在学习了基于8086的x86汇编指令后,继续学习了32位.64位的x86汇编指令.其基本原理与8086基本一致,只是增加了X87浮点单元,以及用于浮点运算和多媒体处理的SIMD(Single Instruction Multiple Data,单指令多数据流)指令. 无论是64位.32位.16位.8位处理器,都是可以(不是绝对)向前兼容的. 1.寄存器变化 32位:(1)通用寄存器扩展到32位,增加到8个(2)增加了x87浮点单元,及相关指令(3)地址总线32位 64位处理器:(1)通用寄存器扩

为什么X86汇编中的mov指令不支持内存到内存的寻址?

在X86汇编中,MOV [0012H], [0016H]这种指令是不允许的,至少得有一个操作数是寄存器.当然,这种问题在用高级语言的时候看不到,感觉好像基本上都是从内存到内存啊,为毛到了汇编就不行了???这个问题在stack overflow有个解释不错: The answer involves a fuller understanding of RAM. Simply stated, RAM can only be in two states, read mode or write mode.

X86汇编5.高级指令详解

最近学习了X86汇编,其实无论是古老的8086还是现在i3/5/7/9,Xeon3/5,在最基本原理上,都是相通的,只是CPU位数,寻址空间,寄存器个数,指令集的扩充等方面有所不同,对于学习,8086永不过时. 转移指令1.转移指令分类:(1)无条件转移指令,如: jmp(2)条件转移指令(3)循环指令,如: loop(4)过程(5)中断 操作符1.offset释义:由编译器处理的符号,功能是取得标号的偏移地址start: mov ax,offset start ;相当于mov ax, 0s:

汇编指令解析

X86架构 [原创]X86汇编之指令格式解析 [原创]汇编指令之OpCode快速入门 [原创]X64汇编之指令格式解析 ARM架构:

如何实现对ARM汇编指令的调试?

学习ARM汇编语言时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在x86平台上执行ARM指令,可以使用qemu模拟器执行ARM汇编指令,具体的调试方法,一起来看看吧. 一.准备ARM汇编程序 首先,我们构造一段简单的ARM汇编程序作为测试代码main.s. .globl _start _start: mov R0,#0 swi 0x00900001 以上汇编指

对X86汇编的理解与入门

本文描述基本的32位X86汇编语言的一个子集,其中涉及汇编语言的最核心部分,包括寄存器结构,数据表示,基本的操作指令(包括数据传送指令.逻辑计算指令.算数运算指令),以及函数的调用规则.个人认为:在理解了本文后,基本可以无障碍地阅读绝大部分标准X86汇编程序.当然,更复杂的指令请参阅Intel相关文档. 1 寄存器. 主要寄存器如下图所示: X86处理器中有8个32位的通用寄存器.由于历史的原因,EAX通常用于计算,ECX通常用于循环变量计数.ESP和EBP有专门用途,ESP指示栈指针(用于指示