x86 体系指令

 
  1. FASM 第二章 - 2.1 x86 体系指令

    Author: 徐艺波  From: xuyibo.org  Updated: 2008-04-17

      官方论坛   本站软件反馈、软件开发交流。
      邮件通知   当更新时自动发送邮件通知。
      评论本文   有什么建议或评论,可以贴一下。
      捐助   你的支持,让我们做的更好。

    2.1 x86 体系指令
    2.1.1 数据传送指令
    2.1.2 类型转换指令
    2.1.3 二进制算术指令
    2.1.4 十进制算术指令
    2.1.5 逻辑指令
    2.1.6 控制转移指令
    2.1.7 I/O 指令
    2.1.8 字符串操作指令
    2.1.9 标志控制指令
    2.1.10 条件操作指令
    2.1.11 其他指令
    2.1.12 系统指令
    2.1.13 FPU 指令
    2.1.14 MMX 指令
    2.1.15 SSE 指令
    2.1.16 SSE2 指令
    2.1.17 SSE3 指令
    2.1.18 AMD 3DNOW!指令
    2.1.19 x86-64长模式指令

    2.1 x86 体系指令

    这一章讲述了汇编语言指令语法和功能。更多的技术信息可以阅读Intel软件开发者手册。

    汇编指令有助记符(指令名称)和0到3个操作符组成。如果有大于两个的操作符,通常第一个为目的操作符第二个为源操作符。每个操作符都可以为寄存器,内存或立即数(操作符语法见1.2节)。每条指令描述后悔有操作符不同用法的例子。

    一些指令用作前缀,可以和其他指令放在同行一起使用,一行也允许有多个前缀。段寄存器也是指令助记符前缀,但推荐在方括号中段重写来替代这些前缀。

    2.1.1 数据传送指令
    mov从源操作符传送字节,字或双字道目的操作符。它可以在通用寄存器之间,通用寄存器到内存,或从内存到通用寄存器间传送数据,但不能在内存间传送数据。它也可以在立即数到通用寄存器或内存,段寄存器到通用寄存器或内存,通用寄存器或内存到段寄存器,控制或调试寄存器到通用寄存器以及通用寄存器到控制或调试寄存器间传送数据。只有当源操作符和目的操作符大小相同时mov才能被汇编。下面是一些例子:

    mov bx,ax      ; 通用寄存器到通用寄存器
    mov [char],al  ; 通用寄存器到内存
    mov bl,[char]  ; 内存到通用寄存器
    mov dl,32      ; 立即数到通用寄存器
    mov [char],32  ; 立即数到内存
    mov ax,ds      ; 段寄存器到通用寄存器
    mov [bx],ds    ; 段寄存器到内存
    mov ds,ax      ; 通用寄存器到段寄存器
    mov ds,[bx]    ; 内存到段寄存器
    mov eax,cr0    ; 控制寄存器到通用寄存器
    mov cr3,ebx    ; 通用寄存器到控制寄存器

    xchg置换两个操作数内容。它可以用来置换两个字节、字或者双字操作数。操作数的顺序并不重要。操作数可以为两个通用寄存器,或者通用寄存器同内存。例如:

    xchg ax,bx     ; 置换两个通用寄存器
    xchg al,[char] ; 寄存器和内存置换

    push递减堆栈指针(esp寄存器),然后传送操作数到esp执行的栈顶。操作数可以为内存,通用寄存器,段寄存器或字、双字立即数。如果操作数为没有指定大小的立即数时,汇编器在16位模式下默认将当作16位值,在32位模式下将当作32位值。pushw和pushd助记符为push指令的变种,分别用来压入16位,32位大小值到堆栈。如果同行后指定了更多参数(空格分隔,而非逗号),将汇编为一串push指令。下面为带有单一操作符的例子:

    push ax       ; 压入通用寄存器到堆栈
    push es       ; 压入段寄存器
    pushw [bx]    ; 压入内存值
    push 1000h    ; 压入立即数

    pusha压入8个通用寄存器的内容到堆栈,这条指令没有操作数。这条指令有两个版本,一个16位的和一个32位的,汇编器自动根据当前模式生成正确的版本,但也可以使用pushaw或pushad助记符重写为只为16位或32位版本。16位版本的这条指令将以以下顺序压入通用寄存器:ax,cx,dx,bx,压入ax前的sp值,bp,si和di。32为版本将以相同顺序压入等价的32位通用寄存器。

    pop传送当前栈顶的字或双字到目的操作符,然后递增esp指向新的栈顶。操作符可以为内存,通用寄存器或段寄存器。popw和popd助记符为pop指令的变种,分别用来弹出字或双字。如果同行后指定了更多参数(空格分隔,而非逗号)将汇编为一串pop指令。

    pop bx        ; 弹出栈顶数据到通用寄存器
    pop ds        ; 弹出到段寄存器
    popw [si]     ; 弹出到内存

    popa弹出堆栈中由pusha指令压入的寄存器,将忽略其中保存的sp(或esp)值。使用popaw或popad助记符来强制汇编16位或32位版本的这条指令。

    2.1.2 类型转换指令

    类型转换指令转换字节为字,字为双字,双字为四字。这些转换可以为符号扩展或零扩展的。符号扩展将用符号位来填充,而零扩展将使用0来填充。

    cwd和cdq分别用来扩展ax和eax大小,并将额外位存储到dx和edx中。转换将使用符号扩展。这些指令没有操作数。

    cbw符号扩展al的值到ax,cwde符号扩展ax到eax。这些指令也没有操作数。

    movsx使用符号扩展将字节转换为字或双字,字转换为双字。movzx类似,只是它使用0扩展。源操作数可以为通用寄存器或内存,目的操作数必须为通用寄存器。例如:

    movsx ax,al         ; 字节寄存器转换为字寄存器
    movsx edx,dl        ; 字节寄存器转换为双字寄存器
    movsx eax,ax        ; 字寄存器转换为双字寄存器
    movsx ax,byte [bx]  ; 字节内存之后为字寄存器
    movsx edx,byte [bx] ; 字节内存转换为双字寄存器
    movsx eax,word [bx] ; 字内存转换为双字寄存器
    2.1.3 二进制算术指令

    add替换目的操作数的值为源操作数和目的操作数的和,并且在溢出时设置CF标志。操作数可以为字节,字或双字。目的操作数可以为通用寄存器或内存,源操作数可以为通用寄存器或立即数,如果目的操作数为寄存器也可以为内存。

    add ax,bx     ; add 寄存器到寄存器
    add ax,[si]   ; add 内存到寄存器
    add [di],al   ; add 寄存器到内存
    add al,48     ; add 立即数到寄存器
    add [char],48 ; add 立即数到内存

    adc和add类似,只是如果设置CF的话结果还将递增1。add后跟着多个adc指令能用来计算大于32位值的和。

    inc将操作数值递增1,它不影响CF。操作数可以为通用寄存器或内存,操作数大小可以为字节,字或双字。

    inc ax        ; 寄存器值递增1
    inc byte [bx] ; 内存值递增1

    sub用目的操作数值减去源操作数,并且用结果替换目的操作数。如果需要借位,将设置CF。操作数规则和add指令相同。

    sbb和sub类似,只是如果设置CF的话结构还将递减1。操作数规则和add质量相同。sub后跟着多个sbb指令能用来计算大于32位值的差。

    dec将操作数值递减1,它不影响CF。操作数规则和inc指令相同。

    cmp用目的操作数减去源操作数,类似sub指令更新标志值,但它不改变源和目的操作符。操作数规则和sub指令相同。

    neg用0减去带符号的整数操作数。这条指令的效果是将带符号的操作数从正数变为负数或者从负数变为正数。操作数规则和inc指令相同。

    xadd交换目的和源操作数,然后载入两个值的和到目的操作数。操作数规则和add指令相同。

    所有上面的二进制算术指令都将更新SF,ZF,PF和OF标志。SF被设置为结果符号位的值,ZF当结果为0时设置为1,PF当低8位存在偶数个1时设置,OF在结果对于正数太大或对于负数太小(超过符号位)以放到目的操作数中时设置。

    mul计算无符号操作数和累加器的积。如果为8位操作数,将和al计算积,16位结果返回到ah和al中。如果4,为16位操作数,将和ax计算积,32位结果返回到dx和ax中。如果为32位操作数,将和eax计算积,64位结果返回到edx和eax中。当结果高半部分不为零时将设置标志CF和OF,否则将清除该标志。操作数规则和inc指令相同。

    imul执行符号乘法运算。这条指令有3种用法。第一种允许一个操作数,和mul指令类似。第二种有两个操作数,此时将计算目的操作数和源操作数的积,并将结果替换目的操作数。目的操作数可以为16位或32位通用寄存器,源操作数可以为通用寄存器,内存或立即数。第三种有3个操作数,目的操作数必须为16位或32位通用寄存器,源操作数可以为通用寄存器或内存,第三种操作数必须为立即数。源操作数乘以立即数并将结果保存到目的寄存器。所有上面三种形式都将计算出双倍大小的结构,并当结果高半部分不为零时设置标志CF和OF。所以第二种和第三种形式也能用作无符号操作数,因为,无论操作数是否为有符号无符号,结果的低半部分是相同的。下面的所有三种形式的乘法指令使用例子:

    imul bl         ; 累加器和寄存器
    imul word [si]  ; 累加器和内存
    imul bx,cx      ; 寄存器和寄存器
    imul bx,[si]    ; 寄存器和内存
    imul bx,10      ; 寄存器和立即数
    imul ax,bx,10   ; 寄存器,立即数,值到寄存器
    imul ax,[si],10 ; 内存,立即数,值到寄存器

    div计算操作数和累加器无符号运算的商。被除数(累加器)为两倍大小的除数(操作数),商和余数和除数有相同尺寸。如果除数为8位,被除数为ax,商和余数分别保存到al和ah中。如果除数为16位,被除数的商的高半部分从dx获取,低半部分从ax获取,商和余数分别保存到ax和dx中。如果除数为32位,被除数的高半部分从edx获取,低半部分从eax获取,商和余数分别保存到eax和edx中。操作数规则和mul指令相同。

    idiv计算操作数和累加器有符号运算的商。它使用和div指令相同的寄存器,操作数的规则也是一样的。

    2.1.4 十进制算术指令

    十进制算术指令用来调整上一节的二进制算术操作以生成有效的压缩或未压缩十进制结果,或调整输入为一个二进制算术操作序列以使该操作能生产一个有效的压缩或解压缩十进制结果。

    daa调整al中两个有效压缩十进制操作数和的值。daa必须跟着两对压缩十进制数(每半字节一个点)的和来得到一对有效压缩十进制数字结果。如果需要进位将设置CF标志。这条指令没有操作数。

    das调整al中两个有效压缩十进制操作数差的值。das必须跟着两对压缩十进制数(每半个字节一个点)的差来得到一对有效压缩十进制数字结果。如果如要进位将设置CF标志。这条指令没有操作数。

    aaa修改al中的内容为有效的未压缩十进制数字,并将高四位清零。aaa必须跟着al中两个有效未压缩十进制操作数和。如果需要进位将设置CF标志并递增ah的值。这条指令没有操作数。

    aas修改al的值为一个有效的未压缩十进制数据,并将

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
x86和ARM指令集是两种常见的计算机体系结构的指令集架构。它们都用于指导计算机硬件执行特定的任务和操作。以下是关于x86和ARM指令集的一些简要信息: x86指令集:x86是一种基于CISC(复杂指令集计算)体系结构的指令集。该指令集最初由英特尔开发,并成为主要的个人计算机和服务器体系结构。x86指令集包含丰富的指令,可执行多种操作,包括算术运算、逻辑运算、数据传输和控制流等。它是一种复杂的指令集,并且具有较高的执行能力和灵活性。凭借广泛的软件支持和计算能力,x86成为桌面和服务器领域最流行的体系结构之一。 ARM指令集:ARM是一种基于RISC(精简指令集计算)体系结构的指令集。它最初由英国公司ARM Holdings开发,并成为移动设备(如智能手机和平板电脑)和嵌入式系统的主要体系结构。ARM指令集设计简洁,指令数量较少,每条指令一般只执行一个简单的操作。与x86相比,ARM指令集执行效率更高,并具有更低的功耗和较小的芯片面积。因此,它成为便携式设备和嵌入式系统中的首选体系结构。 x86和ARM的比较:x86指令集适用于大型多任务处理、复杂的图形操作和计算密集型任务。它具有广泛的软件生态系统和令人称赞的性能。然而,由于复杂指令集的特性,x86架构的芯片更复杂、功耗较高,并且相对较贵。 相比之下,ARM指令集在低功耗设备方面表现出色。ARM芯片的功耗较低,性能较高,并且在移动设备和嵌入式系统中能够提供高度集成的解决方案。此外,由于ARM芯片广泛采用,其生态系统和软件支持也非常庞大。 总结而言,x86和ARM指令集都有各自的优势和适用场景。x86适用于高性能和复杂任务的计算机系统,而ARM则适用于低功耗和便携设备的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值