x86汇编指令

合集下载

x86 汇编判断指令

x86 汇编判断指令

x86 汇编判断指令摘要:一、x86 汇编简介二、判断指令的作用三、x86 汇编中的判断指令1.汇编语言中的条件语句2.比较指令3.跳转指令四、判断指令的应用实例1.简单条件判断2.复杂条件判断五、判断指令在编程中的重要性正文:x86 汇编是一种低级编程语言,用于编写操作系统、驱动程序和嵌入式系统等。

汇编语言中的判断指令是控制程序流程的关键,它们可以根据程序执行过程中的条件来决定接下来的执行路径。

判断指令的作用是根据某些条件来改变程序的执行流程。

在x86 汇编中,判断指令通常用于实现条件语句,如if-else 语句。

通过使用判断指令,程序员可以更加灵活地控制程序的执行流程,实现复杂的逻辑功能。

在x86 汇编中,判断指令主要包括以下几类:1.汇编语言中的条件语句汇编语言中的条件语句主要包括je(等于)、jne(不等于)、jg(大于)、jl(小于)和jge(大于等于)、jle(小于等于)等。

这些条件语句用于根据某些条件来跳转到指定的指令位置。

例如,以下代码实现了一个简单的if-else 语句:```cmp eax, 10jne else_labeljmp end_labelelse_label:mov eax, 20end_label:```2.比较指令比较指令用于比较两个操作数的大小,从而决定程序的执行路径。

在x86 汇编中,比较指令主要包括cmp(比较)、test(测试)等。

例如,以下代码实现了一个比较两个整数大小的功能:```cmp eax, ebx```3.跳转指令跳转指令用于改变程序的执行流程。

在x86 汇编中,跳转指令主要包括jmp(无条件跳转)、jz(零标志跳转)、jnz(非零标志跳转)等。

例如,以下代码实现了一个根据条件跳转到指定位置的功能:```jmp label```判断指令在编程中具有重要意义,它们使得程序员能够根据不同的条件执行不同的操作。

在复杂的程序中,判断指令可以帮助程序员更好地组织代码,提高程序的可读性和可维护性。

x86汇编程序 加法例子

x86汇编程序 加法例子

x86汇编程序加法例子x86汇编语言是一种低级程序设计语言,用于编写计算机程序的一种机器语言。

在x86汇编语言中,加法是最基本的算术运算之一。

下面将列举10个符合要求的x86汇编程序加法例子,并对每个例子进行详细解释。

1. 例子一:```assemblysection .datanumber1 dd 10number2 dd 20result dd 0section .textglobal _start_start:mov eax, [number1] ; 将number1的值加载到寄存器eax 中add eax, [number2] ; 将number2的值加到eax寄存器中 mov [result], eax ; 将eax寄存器中的值保存到result 中; 输出结果mov eax, 4 ; 系统调用编号为4,表示输出mov ebx, 1 ; 文件描述符为1,表示标准输出mov ecx, result ; 输出的字符串地址mov edx, 4 ; 输出的字符串长度int 0x80 ; 系统调用; 退出程序mov eax, 1 ; 系统调用编号为1,表示退出程序 xor ebx, ebx ; 退出码设置为0int 0x80 ; 系统调用```此程序通过使用`mov`和`add`指令来实现加法运算。

首先,将`number1`和`number2`的值加载到寄存器`eax`中,然后使用`add`指令将两个值相加,将结果保存在`eax`中,最后将结果输出到标准输出。

2. 例子二:```assemblysection .datanumber1 db 10number2 db 20result db 0section .textglobal _start_start:mov al, [number1] ; 将number1的值加载到寄存器al中 add al, [number2] ; 将number2的值加到al寄存器中mov [result], al ; 将al寄存器中的值保存到result 中; 输出结果mov eax, 4 ; 系统调用编号为4,表示输出mov ebx, 1 ; 文件描述符为1,表示标准输出mov ecx, result ; 输出的字符串地址mov edx, 1 ; 输出的字符串长度int 0x80 ; 系统调用; 退出程序mov eax, 1 ; 系统调用编号为1,表示退出程序 xor ebx, ebx ; 退出码设置为0int 0x80 ; 系统调用```此程序使用的是8位寄存器`al`进行加法运算。

汇编语言基于x86处理器

汇编语言基于x86处理器

汇编语言基于x86处理器汇编语言是一种低级编程语言,它直接操作计算机硬件进行指令级编程。

在x86架构下,汇编语言主要用于编写操作系统、驱动程序以及底层的系统软件。

以下是一些关于x86汇编语言的参考内容:1. x86处理器的架构和特点:x86处理器系列有很多型号和版本,比如Intel的Pentium和Core系列、AMD的Athlon和Ryzen系列等。

了解每种型号处理器的架构和特点对于编写高效的汇编程序非常重要。

2. 汇编语言的基本语法:汇编语言是一种低级语言,它使用汇编指令来直接操作计算机硬件。

了解汇编语言的基本语法,包括寄存器、指令和操作码等内容,是编写汇编程序的基础。

3. 寄存器和内存:在x86汇编语言中,寄存器是非常重要的概念。

了解常用的寄存器,如通用寄存器、段寄存器以及标志寄存器,以及寄存器的使用方法和操作规则,在编写汇编程序时能够更加灵活地使用寄存器。

4. 指令集和操作码:x86处理器支持的指令集非常丰富,包括算术和逻辑指令、数据传输指令、控制指令等。

了解常用的指令集和操作码,以及它们的使用方法和功能,是编写汇编程序的基础。

5. 汇编程序的编写和调试:了解如何编写和调试汇编程序,包括使用汇编器将汇编代码转换为机器码、使用调试器进行程序的调试和内存的查看等。

学习汇编程序的编写和调试技巧,能够更加高效地完成汇编程序的开发和调试任务。

6. 汇编程序的优化:汇编语言可以直接操作硬件,因此在一些对性能要求较高的场景,使用汇编语言编写程序可以实现更高效的代码。

了解汇编程序的编译器优化和硬件优化方法,可以提高汇编程序的执行效率。

7. 汇编语言应用案例:了解汇编语言在实际项目中的应用案例,包括操作系统、驱动程序、嵌入式系统等。

通过学习实际应用案例,能够更好地理解汇编语言在底层系统软件开发中的重要性。

总之,汇编语言是一种低级编程语言,基于x86处理器的汇编语言编程需要了解x86处理器的架构和特点,掌握汇编语言的基本语法、指令集和操作码,熟悉寄存器和内存的使用方法,以及编写和调试汇编程序的技巧。

leave汇编指令

leave汇编指令

leave汇编指令Leave汇编指令是一种常用的x86汇编指令,用于实现函数的局部变量的销毁和函数返回。

本文将介绍leave汇编指令的基本用法以及它在函数执行过程中的作用。

Leave指令通常用于函数的结束阶段,用于清理函数栈帧中的局部变量,并将堆栈指针(SP)恢复到前一个栈帧的位置。

在执行leave指令之前,通常需要将当前函数的栈帧中的返回值存储到特定的寄存器中(如EAX),以便在函数返回后使用。

Leave指令的语法格式如下:```leave```它的执行步骤如下:1. 将基址指针(EBP)的值赋给堆栈指针(ESP)。

这将回收当前函数的栈帧所占用的栈空间,实现局部变量的销毁。

2. 将前一个栈帧的基址指针(保存在当前栈帧中的EBP)的值赋给基址指针(EBP)。

这将恢复调用函数之前的栈帧。

通过上述步骤,leave指令可以高效地清理函数的局部变量,并将堆栈指针恢复到调用函数之前的状态,实现函数的正常返回。

除了简单的leave指令,有些汇编指令集提供了更高级的指令,可以一次性完成函数的结尾工作,包括销毁局部变量、恢复堆栈指针和将返回值存储到指定寄存器中。

这些指令通常是基于leave指令的扩展,并提供了更高的执行效率。

总结来说,leave指令是一种常用的汇编指令,用于清理函数的局部变量并恢复堆栈指针,实现函数的正常返回。

它在函数执行过程中起到了重要的作用,帮助程序员高效地管理内存和实现函数调用。

当我们编写汇编程序时,需要充分理解和使用leave指令,以确保程序的正确性和性能。

(本文仅供参考,具体使用时请结合具体的编译器和平台进行使用。

)。

汇编语言的种类

汇编语言的种类

汇编语言的种类汇编语言是计算机领域中的一门编程语言,它与机器语言密切相关,用于书写可以被计算机直接执行的程序代码。

汇编语言直接操作计算机底层硬件,因此在性能和效果上具有很大优势。

在汇编语言中,不同的体系结构和处理器都有不同的指令集和语法规则,这导致了汇编语言的种类繁多。

本文将介绍几种常见的汇编语言。

1. x86汇编语言x86汇编语言是最为广泛应用的汇编语言之一,在PC和服务器领域得到广泛使用。

x86指令集是英特尔和AMD等处理器厂商所采用的指令集架构,在x86汇编语言中,可以直接操作寄存器、内存以及其他外设,具有很高的灵活性和可操作性。

x86汇编语言使用Intel语法和AT&T语法两种不同的语法规则,常用的编译器有MASM、NASM和GAS。

2. ARM汇编语言ARM汇编语言广泛应用于移动设备、嵌入式系统和物联网等领域。

ARM处理器以其低功耗、高性能和内容丰富的架构而闻名,ARM汇编语言可以直接操作处理器寄存器、存储器和外设,具有很好的可移植性和可扩展性。

ARM汇编语言使用ARM体系结构定义的指令集和语法规则,常用的编译器有ARM汇编器和GNU汇编器等。

3. MIPS汇编语言MIPS汇编语言被广泛应用在嵌入式系统、数字信号处理以及网络设备等领域。

MIPS处理器以其简洁的指令集和高效的架构而著称,MIPS汇编语言可以直接控制寄存器、存储器以及其他外设,具有很高的执行效率和指令流水线能力。

MIPS汇编语言使用MIPS体系结构定义的指令集和语法规则,常用的编译器有MIPS汇编器。

4. PowerPC汇编语言PowerPC汇编语言主要应用于IBM PowerPC架构的服务器、工作站以及游戏机等领域。

PowerPC处理器以其高性能和可扩展性而著称,PowerPC汇编语言可以直接操作处理器寄存器、存储器和外设,具有很好的可移植性和性能表现。

PowerPC汇编语言使用PowerPC指令集和语法规则,常见的编译器有PowerPC汇编器。

X86MOVSBMOVSWMOVSDMOVSQ指令详解

X86MOVSBMOVSWMOVSDMOVSQ指令详解

X86MOVSBMOVSWMOVSDMOVSQ指令详解1. SDM指令功能描述(MOVS/MOVSB/MOVSW/MOVSD/MOVSQ)MOVS/MOVSB/MOVSW/MOVSD/MOVSQ)总体描述:从DS:SI(16-bit)/DS:ESI(32-bit)/RSI(64-bit)指⽰的地址中复制⼀个byte/word/dword/qword到ES:DI(16-bit)/ES:EDI(32-bit)/RDI(64-bit)指⽰的地址中。

(R)(E)SI,(R)(E)DI根据eflags寄存器中DF的标志位决定是⾃增还是⾃减1/2/4/8。

注1:SDM中描述了两种汇编形式,显式指定操作数以及隐式指定。

但⽆论指定如何源操作数和⽬的操作数都是上述过程所指定的操作数。

汇编⾥的指定只⽤来识别数据宽度。

注2:SDM中MOVSD这条指令助记符对应两条不同指令,另⼀条为操作浮点数寄存器⽤。

伪代码⽰例代码⽂章标签:个⼈分类:▼查看关于本篇⽂章更多信息⾮64位下:DEST <- SRC DataLength = 1/2/4;if (EFLAGS.DF == 0) { (E)SI += DataLength; (E)DI += DataLength;}else { (E)SI -= DataLength; (E)DI -= DataLength;}64位下:DEST <- SRC DataLength = 1/2/4/8;if (EFLAGS.DF == 0) { RSI += DataLength; RDI += DataLength;}else { RSI -= DataLength; RDI -= DataLength;}12345678910111213141516171819202122232425do_move: movw %ax , %es # destination segment addw $0x1000, %ax cmp $0x9000, %ax jz end_move movw %ax , %ds # source segment sub %di , %di sub %si , %si movw $0x8000, %cx rep movsw jmp do_move123456789101112。

x86架构汇编指令

x86架构汇编指令x86架构汇编指令是一种底层的机器语言指令集,用于在x86架构的计算机上执行任务。

它包含了一系列指令,用于操作寄存器、内存和其他硬件设备,以及进行算术和逻辑运算等操作。

本文将介绍几个常用的x86架构汇编指令,包括MOV、ADD、SUB和JMP。

1. MOV指令:MOV指令用于将数据从一个位置复制到另一个位置。

它的语法如下:MOV destination, source其中destination可以是一个寄存器或内存地址,source可以是一个寄存器、内存地址或立即数。

例如,MOV AX, BX将BX寄存器的值复制到AX寄存器中。

2. ADD指令:ADD指令用于将两个数相加,并将结果存储在目标位置。

它的语法如下:ADD destination, source其中destination可以是一个寄存器或内存地址,source可以是一个寄存器、内存地址或立即数。

例如,ADD AX, BX将AX寄存器的值与BX寄存器的值相加,并将结果存储在AX寄存器中。

3. SUB指令:SUB指令用于将两个数相减,并将结果存储在目标位置。

它的语法如下:SUB destination, source其中destination可以是一个寄存器或内存地址,source可以是一个寄存器、内存地址或立即数。

例如,SUB AX, BX将AX寄存器的值减去BX寄存器的值,并将结果存储在AX寄存器中。

4. JMP指令:JMP指令用于无条件地跳转到指定的地址。

它的语法如下:JMP destination其中destination可以是一个标签或地址。

例如,JMP LOOP将跳转到LOOP标签所在的位置。

除了上述指令外,x86架构汇编还包括许多其他指令,如CMP、AND、OR、NOT、XOR等,用于进行比较、逻辑运算和位操作等。

这些指令可以组合使用,以实现复杂的功能。

x86架构汇编指令的编写需要遵循一定的规范和语法。

每条指令都由一个助记符和操作数组成,它们之间用逗号隔开。

x86 str汇编指令

x86 str汇编指令
x86汇编指令中的str指令用于将数据从内存移动到寄存器中。

在x86架构中,mov指令可以实现相同的功能,但str指令具有一些优势。

首先,str指令遵循ARM汇编语义,即“加载/存储”(Load/Store)操作。

在ARM架构中,数据从内存到CPU之间的移动必须通过ldr/str 指令完成。

这与x86架构有所不同,x86架构中的mov指令可以在寄存器之间移动数据,或者将立即数移动到寄存器中。

其次,str指令在移动数据时具有更高的灵活性。

例如,str指令可以加载内存中的一个字节、字或双字数据到寄存器中,而mov指令只能移动一个字节或字。

此外,str指令还可以加载内存中的相对地址,这在某些场景下非常有用。

然而,需要注意的是,x86架构中并没有真正的ldr指令。

在x86汇编中,mov指令可以实现类似的功能,将从内存中某个地址的数据移动到寄存器中。

而str指令在x86架构中主要用作存储器到寄存器的数据传送。

总之,x86汇编指令中的str指令用于将数据从内存移动到寄存器,与mov指令具有相似的功能,但str指令在某些方面更具优势,例如
加载内存中的相对地址。

然而,需要注意的是,x86架构中并没有真正的ldr指令,而是使用mov指令来实现类似的功能。

x86汇编指令集大全

x86汇编指令集⼤全-----------------------------------汇编指令集太多,如果不⽤就会忘记,所以将i处理器官⽅的指令集⼤全写到博客上,有需要的⼈可以参考⼀下!---------- ⼀、数据传输指令 ----------------------------------------------------它们在存贮器和寄存器、寄存器和输⼊输出端⼝之间传送数据.1. 通⽤数据传送指令MOV 传送字或字节.MOVSX 先符号扩展,再传送.MOVZX 先零扩展,再传送.PUSH 把字压⼊堆栈.POP 把字弹出堆栈.PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压⼊堆栈.POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压⼊堆栈.POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.BSWAP 交换32位寄存器⾥字节的顺序XCHG 交换字或字节.(⾄少有⼀个操作数为寄存器,段寄存器不可作为操作数)CMPXCHG ⽐较并交换操作数.(第⼆个操作数必须为累加器AL/AX/EAX)XADD 先交换再累加.(结果在第⼀个操作数⾥)XLAT 字节查表转换.----BX指向⼀张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL)2. 输⼊输出端⼝传送指令.IN I/O端⼝输⼊. ( 语法: IN 累加器, {端⼝号│DX} )OUT I/O端⼝输出. ( 语法: OUT {端⼝号│DX},累加器 )输⼊输出端⼝由⽴即⽅式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535.3. ⽬的地址传送指令.LEA 装⼊有效地址.例: LEA DX,string ;把偏移地址存到DX.LDS 传送⽬标指针,把指针内容装⼊DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.LES 传送⽬标指针,把指针内容装⼊ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI.LFS 传送⽬标指针,把指针内容装⼊FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.LGS 传送⽬标指针,把指针内容装⼊GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.LSS 传送⽬标指针,把指针内容装⼊SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.4. 标志传送指令.LAHF 标志寄存器传送,把标志装⼊AH.SAHF 标志寄存器传送,把AH内容装⼊标志寄存器.PUSHF 标志⼊栈.POPF 标志出栈.PUSHD 32位标志⼊栈.POPD 32位标志出栈.---------- ⼆、算术运算指令 ------------------------------------------ADC 带进位加法.INC 加 1.AAA 加法的ASCII码调整.DAA 加法的⼗进制调整.SUB 减法.SBB 带借位减法.DEC 减 1.NEG 求反(以 0 减之).CMP ⽐较.(两操作数作减法,仅修改标志位,不回送结果).AAS 减法的ASCII码调整.DAS 减法的⼗进制调整.MUL ⽆符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),AAM 乘法的ASCII码调整.DIV ⽆符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或商回送AX,余数回送DX, (字运算).IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或商回送AX,余数回送DX, (字运算).AAD 除法的ASCII码调整.CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)---------- 三、逻辑运算指令 ------------------------------------AND 与运算.OR 或运算.XOR 异或运算.NOT 取反.TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).SHL 逻辑左移.SAL 算术左移.(=SHL)SHR 逻辑右移.SAR 算术右移.(=SHR)ROL 循环左移.ROR 循环右移.RCL 通过进位的循环左移.RCR 通过进位的循环右移.以上⼋种移位指令,其移位次数可达255次.移位⼀次时, 可直接⽤操作码. 如 SHL AX,1.移位>1次时, 则由寄存器CL给出移位次数.如 MOV CL,04 SHL AX,CL---------- 四、串指令 ---------------------------------------------DS:SI 源串段寄存器 :源串变址.ES:DI ⽬标串段寄存器:⽬标串变址.CX 重复次数计数器.AL/AX 扫描值.D标志 0表⽰重复操作中SI和DI应⾃动增量; 1表⽰应⾃动减量.Z标志⽤来控制扫描或⽐较操作的结束.MOVS 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )CMPS 串⽐较.( CMPSB ⽐较字符. CMPSW ⽐较字. )SCAS 串扫描.把AL或AX的内容与⽬标串作⽐较,⽐较结果反映在标志位.LODS 装⼊串.把源串中的元素(字或字节)逐⼀装⼊AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. ) STOS 保存串.是LODS的逆过程.REP 当CX/ECX<>0时重复.REPE/REPZ 当ZF=1或⽐较结果相等,且CX/ECX<>0时重复.REPNE/REPNZ 当ZF=0或⽐较结果不相等,且CX/ECX<>0时重复.REPC 当CF=1且CX/ECX<>0时重复.REPNC 当CF=0且CX/ECX<>0时重复.---------- 五、程序转移指令 -------------------------------1. ⽆条件转移指令 (长转移)JMP ⽆条件转移指令CALL 过程调⽤RET/RETF 过程返回.2. 条件转移指令 (短转移,-128到+127的距离内)( 当且仅当(SF XOR OF)=1时,OP1<OP2 )JA/JNBE 不⼩于或不等于时转移.JAE/JNB ⼤于或等于转移.JB/JNAE ⼩于转移.JBE/JNA ⼩于或等于转移.以上四条,测试⽆符号整数运算的结果(标志C和Z).JG/JNLE ⼤于转移.JGE/JNL ⼤于或等于转移.JL/JNGE ⼩于转移.JLE/JNG ⼩于或等于转移.以上四条,测试带符号整数运算的结果(标志S,O和Z).JE/JZ 等于转移.JNE/JNZ 不等于时转移.JC 有进位时转移.JNC ⽆进位时转移.JNO 不溢出时转移.JNP/JPO 奇偶性为奇数时转移.JNS 符号位为 "0" 时转移.JO 溢出转移.JP/JPE 奇偶性为偶数时转移.JS 符号位为 "1" 时转移.3. 循环控制指令(短转移)LOOP CX不为零时循环.LOOPE/LOOPZ CX不为零且标志Z=1时循环.LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.JCXZ CX为零时转移.JECXZ ECX为零时转移.4. 中断指令INT 中断指令INTO 溢出中断IRET 中断返回5. 处理器控制指令HLT 处理器暂停, 直到出现中断或复位信号才继续.WAIT 当芯⽚引线TEST为⾼电平时使CPU进⼊等待状态.ESC 转换到外处理器.LOCK 封锁总线.NOP 空操作.STC 置进位标志位.CLC 清进位标志位.CMC 进位标志取反.STD 置⽅向标志位.CLD 清⽅向标志位.STI 置中断允许位.CLI 清中断允许位.---------- 六、伪指令 ------------------------------------DW 定义字(2字节).PROC 定义过程.ENDP 过程结束.SEGMENT 定义段.ASSUME 建⽴段寄存器寻址.ENDS 段结束.END 程序结束.---------- 七、处理机控制指令:标志处理指令 -----------CLC 进位位置0指令CMC 进位位求反指令STC 进位位置为1指令CLD ⽅向标志置1指令STD ⽅向标志位置1指令CLI 中断标志置0指令STI 中断标志置1指令NOP ⽆操作HLT 停机WAIT 等待ESC 换码LOCK 封锁========== 浮点运算指令集 =========⼀、控制指令(带9B的控制指令前缀F变为FN时浮点不检查,机器码去掉9B)----FINIT 初始化浮点部件机器码 9B DB E3FCLEX 清除异常机器码 9B DB E2FDISI 浮点检查禁⽌中断机器码 9B DB E1FENI 浮点检查禁⽌中断⼆机器码 9B DB E0WAIT 同步CPU和FPU 机器码 9BFWAIT 同步CPU和FPU 机器码 D9 D0FNOP ⽆操作机器码 DA E9FXCH 交换ST(0)和ST(1) 机器码 D9 C9FXCH ST(i) 交换ST(0)和ST(i) 机器码 D9 C1iiiFSTSW ax 状态字到ax 机器码 9B DF E0FSTSW word ptr mem 状态字到mem 机器码 9B DD mm111mmmFLDCW word ptr mem mem到状态字机器码 D9 mm101mmmFSTCW word ptr mem 控制字到mem 机器码 9B D9 mm111mmmFLDENV word ptr mem mem到全环境机器码 D9 mm100mmmFSTENV word ptr mem 全环境到mem 机器码 9B D9 mm110mmmFRSTOR word ptr mem mem到FPU状态机器码 DD mm100mmmFSAVE word ptr mem FPU状态到mem 机器码 9B DD mm110mmmFFREE ST(i) 标志ST(i)未使⽤机器码 DD C0iiiFDECSTP 减少栈指针1->0 2->1 机器码 D9 F6FINCSTP 增加栈指针0->1 1->2 机器码 D9 F7FSETPM 浮点设置保护机器码 DB E4---------- ⼆、数据传送指令 -----------------------------------------FLDZ 将0.0装⼊ST(0) 机器码 D9 EEFLD1 将1.0装⼊ST(0) 机器码 D9 E8FLDPI 将π装⼊ST(0) 机器码 D9 EBFLDL2T 将ln10/ln2装⼊ST(0) 机器码 D9 E9FLDL2E 将1/ln2装⼊ST(0) 机器码 D9 EAFLDLG2 将ln2/ln10装⼊ST(0) 机器码 D9 ECFLDLN2 将ln2装⼊ST(0) 机器码 D9 EDFLD real4 ptr mem 装⼊mem的单精度浮点数机器码 D9 mm000mmmFLD real8 ptr mem 装⼊mem的双精度浮点数机器码 DD mm000mmmFLD real10 ptr mem 装⼊mem的⼗字节浮点数机器码 DB mm101mmmFILD word ptr mem 装⼊mem的⼆字节整数机器码 DF mm000mmmFILD dword ptr mem 装⼊mem的四字节整数机器码 DB mm000mmmFILD qword ptr mem 装⼊mem的⼋字节整数机器码 DF mm101mmmFBLD tbyte ptr mem 装⼊mem的⼗字节BCD数机器码 DF mm100mmmFST real4 ptr mem 保存单精度浮点数到mem 机器码 D9 mm010mmmFST real8 ptr mem 保存双精度浮点数到mem 机器码 DD mm010mmmFIST word ptr mem 保存⼆字节整数到mem 机器码 DF mm010mmmFIST dword ptr mem 保存四字节整数到mem 机器码 DB mm010mmmFSTP real4 ptr mem 保存单精度浮点数到mem并出栈机器码 D9 mm011mmmFSTP real8 ptr mem 保存双精度浮点数到mem并出栈机器码 DD mm011mmmFSTP real10 ptr mem 保存⼗字节浮点数到mem并出栈机器码 DB mm111mmmFISTP word ptr mem 保存⼆字节整数到mem并出栈机器码 DF mm011mmmFISTP dword ptr mem 保存四字节整数到mem并出栈机器码 DB mm011mmmFISTP qword ptr mem 保存⼋字节整数到mem并出栈机器码 DF mm111mmmFBSTP tbyte ptr mem 保存⼗字节BCD数到mem并出栈机器码 DF mm110mmmFCMOVB ST(0),ST(i) <时传送机器码 DA C0iiiFCMOVBE ST(0),ST(i) <=时传送机器码 DA D0iiiFCMOVE ST(0),ST(i) =时传送机器码 DA C1iiiFCMOVNB ST(0),ST(i) >=时传送机器码 DB C0iiiFCMOVNBE ST(0),ST(i) >时传送机器码 DB D0iiiFCMOVNE ST(0),ST(i) !=时传送机器码 DB C1iiiFCMOVNU ST(0),ST(i) 有序时传送机器码 DB D1iiiFCMOVU ST(0),ST(i) ⽆序时传送机器码 DA D1iii---------- 三、⽐较指令 -----------------------------------------FCOM ST(0)-ST(1) 机器码 D8 D1FCOMI ST(0),ST(i) ST(0)-ST(1) 机器码 DB F0iiiFCOMIP ST(0),ST(i) ST(0)-ST(1)并出栈机器码 DF F0iiiFCOM real4 ptr mem ST(0)-实数mem 机器码 D8 mm010mmmFCOM real8 ptr mem ST(0)-实数mem 机器码 DC mm010mmmFICOM word ptr mem ST(0)-整数mem 机器码 DE mm010mmmFICOM dword ptr mem ST(0)-整数mem 机器码 DA mm010mmmFICOMP word ptr mem ST(0)-整数mem并出栈机器码 DE mm011mmmFICOMP dword ptr mem ST(0)-整数mem并出栈机器码 DA mm011mmmFTST ST(0)-0 机器码 D9 E4FUCOM ST(i) ST(0)-ST(i) 机器码 DD E0iiiFUCOMP ST(i) ST(0)-ST(i)并出栈机器码 DD E1iiiFUCOMPP ST(0)-ST(1)并⼆次出栈机器码 DA E9FXAM ST(0)规格类型机器码 D9 E5---------- 四、运算指令 --------------------------------------FADD 把⽬的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在⽬的操作数后的变量或堆栈缓存器) 相加,并将结果存⼊⽬的操作数FADDP ST(i),ST 这个指令是使⽬的操作数加上 ST 缓存器,并弹出 ST 缓存器,⽽⽬的操作数必须是堆栈缓存器的其中之⼀,最后不管⽬的操作数为何,经弹出⼀次后,⽬的操作数会变成上⼀个堆栈缓存器了FIADD FIADD 是把 ST 加上来源操作数,然后再存⼊ ST 缓存器,来源操作数必须是字组整数或短整数形态的变数FSUB 减FSUBPFSUBR 减数与被减数互换FSUBRPFISUBFISUBRFMUL 乘FMULPFIMULFDIV 除FDIVPFDIVRFDIVRPFIDIVFIDIVRFCHS 改变 ST 的正负值FABS 把 ST 之值取出,取其绝对值后再存回去。

x86汇编sub指令

x86汇编sub指令x86汇编中的sub指令用于执行减法操作。

它的基本语法如下:sub destination, source其中,destination是目标操作数,而source是源操作数。

sub指令的功能是将源操作数的值减去目标操作数的值,并将结果存储到目标操作数中。

在使用sub指令时,需要注意以下几点:1. 操作数的大小:- 如果目标操作数和源操作数都是字节大小的变量,那么执行sub指令时,将会进行无符号字节级别的减法运算。

- 如果目标操作数和源操作数都是字大小的变量,那么执行sub指令时,将会进行无符号字级别的减法运算。

- 如果目标操作数和源操作数都是双字大小的变量,那么执行sub指令时,将会进行无符号双字级别的减法运算。

2. 符号位的处理:- 当执行sub指令时,会根据运算结果设置CF(Carry Flag)标志和OF(Overflow Flag)标志。

如果结果小于0,则CF标志会被设置为1,否则为0。

如果结果溢出,则OF标志会被设置为1,否则为0。

接下来,我将为你提供两个示例来说明sub指令的使用。

示例1:字节级别的减法运算```asmsection .datavar1 db 10 ; 目标操作数var2 db 5 ; 源操作数section .textglobal _start_start:mov al, [var1] ; 将目标操作数加载到AL寄存器中sub al, [var2] ; 将源操作数从AL寄存器中减去mov [var1], al ; 将结果存储到目标操作数中; 可以在这里读取目标操作数的值,然后进行打印等操作; 退出程序mov eax, 1xor ebx, ebxint 0x80```示例2:双字级别的减法运算```asmsection .datavar1 dd 100 ; 目标操作数var2 dd 50 ; 源操作数section .textglobal _start_start:mov eax, [var1] ; 将目标操作数加载到EAX寄存器中sub eax, [var2] ; 将源操作数从EAX寄存器中减去mov [var1], eax ; 将结果存储到目标操作数中; 可以在这里读取目标操作数的值,然后进行打印等操作; 退出程序mov eax, 1xor ebx, ebxint 0x80```这两个示例展示了如何使用sub指令进行减法运算,并将结果存储在目标操作数中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

简明X86汇编语言教程原创:司徒彦南2002年4月8日徐远超于2010-02-25收集整理 2010-03-10第2次补充 2010-03-25第3次补充目录第Ο章 写在前面 (2)第一章汇编语言简介 (3)第二章认识处理器 (4)2.1 寄存器 (4)2.2 使用寄存器 (6)第三章操作内存 (12)3.1 实模式 (12)3.2 保护模式 (16)3.3 操作内存 (19)3.4 串操作 (21)3.5 关于保护模式中内存操作的一点说明 (22)3.6 堆栈 (23)本章小结 (25)第四章利用子程序与中断 (25)4.1 子程序 (25)4.2 中断 (31)第五章编译优化概述 (34)5.1 循环优化:强度削减和代码外提 (36)5.2 局部优化:表达式预计算和子表达式提取 (37)5.3 全局寄存器优化 (38)5.4 x86体系结构上的并行最大化和指令封包 (40)5.5 存储优化 (42)第六章 Linux X86汇编程序设计 (46)6.1编译和链接 (46)6.2基本示例 (46)第七章 X86汇编指令集汇总 (47)一.数据传输指令 (47)二、算术运算指令 (49)三、逻辑运算指令 (49)四、串指令 (50)五、程序转移指令 (50)六、伪指令 (52)七、寄存器 (52)八、位操作指令,处理器控制指令 (52)九、FPU instructions (54)第八章 GCC内联汇编基础 (54)1. GCC汇编格式 (55)2.内联汇编基本形式 (56)3. 扩展形式内联汇编 (56)4. 深入constra (59)5.结束语 (63)第Ο章写在前面我不想夸大或者贬低汇编语言。

但我想说,汇编语言改变了20世纪的历史。

与前辈相比,我们这一代编程人员足够的幸福,因为我们有各式各样的编程语言,我们可以操作键盘、坐在显示器面前,甚至使用鼠标、语音识别。

我们可以使用键盘、鼠标来驾驭“个人计算机”,而不是和一群人共享一台使用笨重的继电器、开关去操作的巨型机。

相比之下,我们的前辈不得不使用机器语言编写程序,他们甚至没有最简单的汇编程序来把助记符翻译成机器语言,而我们可以从上千种计算机语言中选择我们喜欢的一种,而汇编,虽然不是一种“常用”的具有“快速原型开发”能力的语言,却也是我们可以选择的语言中的一种。

每种计算机都有自己的汇编语言——没必要指望汇编语言的可移植性,选择汇编,意味着选择性能而不是可移植或便于调试。

这份文档中讲述的是x86汇编语言,此后的“汇编语言”一词,如果不明示则表示IA32上的x86汇编语言。

汇编语言是一种易学,却很难精通的语言。

回想当年,我从初学汇编到写出第一个可运行的程序,只用了不到4个小时;然而直到今天,我仍然不敢说自己精通它。

编写快速、高效、并且能够让处理器“很舒服地执行”的程序是一件很困难的事情,如果利用业余时间学习,通常需要2-3年的时间才能做到。

这份教材并不期待能够教给你大量的汇编语言技巧。

对于读者来说,x86汇编语言"就在这里"。

然而,不要僵化地局限于这份教材讲述的内容,因为它只能告诉你汇编语言是“这样一回事”。

学好汇编语言,更多的要靠一个人的创造力与悟性,我可以告诉你我所知道的技巧,但肯定这是不够的。

一位对我的编程生涯产生过重要影响的人曾经对我说过这么一句话:写汇编语言程序不是汇编语言最难的部分,创新才是。

我想,愿意看这份文档的人恐怕不会问我“为什么要学习汇编语言”这样的问题;不过,我还是想说几句:首先,汇编语言非常有用,我个人主张把它作为C语言的先修课程,因为通过学习汇编语言,你可以了解到如何有效地设计数据结构,让计算机处理得更快,并使用更少的存储空间;同时,学习汇编语言可以让你熟悉计算机内部运行机制,并且,有效地提高调试能力。

就我个人的经验而言,调试一个非结构化的程序的困难程度,要比调试一个结构化的程序的难度高很多,因为“结构化”是以牺牲运行效率来提高可读性与可调试性,这对于完成一般软件工程的编码阶段是非常必要的。

然而,在一些地方,比如,硬件驱动程序、操作系统底层,或者程序中经常需要执行的代码,结构化程序设计的这些优点有时就会被它的低效率所抹煞。

另外,如果你想真正地控制自己的程序,只知道源代码级的调试是远远不够的。

浮躁的人喜欢说,用C++写程序足够了,甚至说,他不仅仅掌握C++,而且精通STL、MFC。

我不赞成这个观点,掌握上面的那些是每一个编程人员都应该做到的,然而C++只是我们"常用"的一种语言,它不是编程的全部。

低层次的开发者喜欢说,嘿,C++是多么的强大,它可以做任何事情——这不是事实。

便于维护、调试,这些确实是我们的追求目标,但是,写程序不能仅仅追求这个目标(还有性能、功耗整理者注),因为我们最终的目的是满足设计需求,而不是个人非理性的理想。

这份教材适合已经学习过某种结构化程序设计语言的读者。

其内容基于我在1995年给别人讲述汇编语言时所写的讲义。

当然,如大家所希望的,它包含了最新的处理器所支持的特性,以及相应的内容。

我假定读者已经知道了程序设计的一些基本概念,因为没有这些是无法理解汇编语言程序设计的;此外,我希望读者已经有了比较良好的程序设计基础,因为如果你缺乏对于结构化程序设计的认识,编写汇编语言程序很可能很快就破坏了你的结构化编程习惯,大大降低程序的可读性、可维护性,最终让你的程序陷于不得不废弃的代码堆之中。

基本上,这份文档撰写的目标是尽可能地便于自学。

不过,它对你也有一些要求,尽管不是很高,但我还是强调一下。

学习汇编语言,你需要:胆量。

不要害怕去接触那些计算机的内部工作机制。

知识。

了解计算机常用的数制,特别是二进制、十六进制、八进制,以及计算机保存数据的方法。

开放。

接受汇编语言与高级语言的差异,而不是去指责它如何的不好读。

经验。

要求你拥有任意其他编程语言的一点点编程经验。

头脑。

祝您编程愉快!第一章汇编语言简介先说一点和实际编程关系不太大的东西。

当然,如果你迫切的想看到更实质的内容,完全可以先跳过这一章。

那么,我想可能有一个问题对于初学汇编的人来说非常重要,那就是:汇编语言到底是什么?汇编语言是一种最接近计算机核心的编码语言。

不同于任何高级语言,汇编语言几乎可以完全和机器语言一一对应。

不错,我们可以用机器语言写程序,但现在除了没有汇编程序的那些电脑之外,直接用机器语言写超过1000条以上指令的人大概只能算作那些被我们成为“圣人”的牺牲者一类了。

毕竟,记忆一些短小的助记符、由机器去考虑那些琐碎的配位过程和检查错误,比记忆大量的随计算机而改变的十六进制代码、可能弄错而没有任何提示要强的多。

熟练的汇编语言编码员甚至可以直接从十六进制代码中读出汇编语言的大致意思。

当然,我们有更好的工具——汇编器和反汇编器。

简单地说,汇编语言就是机器语言的一种可以被人读懂的形式,只不过它更容易记忆。

至于宏汇编,则是包含了宏支持的汇编语言,这可以让你编程的时候更专注于程序本身,而不是忙于计算和重写代码。

汇编语言除了机器语言之外最接近计算机硬件的编程语言。

由于它如此的接近计算机硬件,因此,它可以最大限度地发挥计算机硬件的性能。

用汇编语言编写的程序的速度通常要比高级语言和C/C++快很多--几倍,几十倍,甚至成百上千倍。

当然,解释语言,如解释型LISP,没有采用JIT技术的Java虚拟机中运行的Java等等,其程序速度更无法与汇编语言程序同日而语。

永远不要忽视汇编语言的高速。

实际的应用系统中,我们往往会用汇编彻底重写某些经常调用的部分以期获得更高的性能。

应用汇编也许不能提高你的程序的稳定性,但至少,如果你非常小心的话,它也不会降低稳定性;与此同时,它可以大大地提高程序的运行速度。

我强烈建议所有的软件产品在最后Release之前对整个代码进行Profile,并适当地用汇编取代部分高级语言代码。

至少,汇编语言的知识可以告诉你一些有用的东西,比如,你有多少个寄存器可以用。

有时,手工的优化比编译器的优化更为有效,而且,你可以完全控制程序的实际行为。

我想我在罗嗦了。

总之,在我们结束这一章之前,我想说,不要在优化的时候把希望完全寄托在编译器上——现实一些,再好的编译器也不可能总是产生最优的代码。

第二章认识处理器中央处理器(CPU)在微机系统处于“领导核心”的地位。

汇编语言被编译成机器语言之后,将由处理器来执行。

那么,首先让我们来了解一下处理器的主要作用,这将帮助你更好地驾驭它。

典型的处理器的主要任务包括从内存中获取机器语言指令,译码,执行根据指令代码管理它自己的寄存器根据指令或自己的需要修改内存的内容响应其他硬件的中断请求。

一般说来,处理器拥有对整个系统的所有总线的控制权。

对于Intel平台而言,处理器拥有对数据、内存和控制总线的控制权,根据指令控制整个计算机的运行。

在以后的章节中,我们还将讨论系统中同时存在多个处理器的情况。

处理器中有一些寄存器,这些寄存器可以保存特定长度的数据。

某些寄存器中保存的数据对于系统的运行有特殊的意义。

新的处理器往往拥有更多、具有更大字长的寄存器,提供更灵活的取指、寻址方式。

2.1 寄存器如前所述,处理器中有一些可以保存数据的地方被称作寄存器。

寄存器可以被装入数据,你也可以在不同的寄存器之间移动这些数据,或者做类似的事情。

基本上,像四则运算、位运算等这些计算操作,都主要是针对寄存器进行的。

首先让我来介绍一下80386上最常用的4个通用寄存器。

先瞧瞧下面的图形,试着理解一下:上图中,数字表示的是位。

我们可以看出,EAX是一个32-bit寄存器。

同时,它的低16-bit又可以通过AX这个名字来访问;AX又被分为高、低8bit两部分,分别由AH和AL 来表示。

对于EAX、AX、AH、AL的改变同时也会影响与被修改的那些寄存器的值。

从而事实上只存在一个32-bit的寄存器EAX,而它可以通过4种不同的途径访问。

也许通过名字能够更容易地理解这些寄存器之间的关系。

EAX中的E的意思是“扩展的”,整个EAX的意思是扩展的AX。

X的意思Intel没有明示,我个人认为表示它是一个可变的量。

而AH、AL中的H和L分别代表高和低。

为什么要这么做呢?主要由于历史原因。

早期的计算机是8位的,8086是第一个16位处理器,其通用寄存器的名字是AX,BX等等;80386是Intel推出的第一款IA-32系列处理器,所有的寄存器都被扩充为32位。

为了能够兼容以前的16位应用程序,80386不能将这些寄存器依旧命名为AX、BX,并且简单地将他们扩充为32位——这将增加处理器在处理指令方面的成本。

Intel微处理器的寄存器列表(在本章只介绍80386的寄存器,MMX寄存器以及其他新一代处理器的新寄存器将在以后的章节介绍)通用寄存器下面介绍通用寄存器及其习惯用法。

相关文档
最新文档