汇编指令(x86的)

基础计算符

ADD 加法
SUB 减法
DIV 除法
IDIV 整数除法
CMP 比较 等于 (c语言 == )
MUL 乘法
INC 自增++
DEC 自减--
ADC 带进位加法
AAA 加法进行ACII码调整
DAA 加法十进制调整
SBB 带借位减法
DEC 减1 
AAS 减法的ASCII调整
DAS 减法十进制调整
IMUL 整数乘法
AAM 乘法的ascii 调整
AAD 除法ASCII调整

进位转移符号

JC 有进位时转移(进位标志是1跳转)
JNC 无进位时转移
JNO 不溢出时转移
JNP/JPO 奇数转移
JNS 符号为0转移
JO 溢出转移
JP/JPE 偶数转移
JS 符号为1转移
LOOPE(Loop if Equal)指令用于在一个循环中根据ZF(Zero Flag)标志的值来决定是否继续循环。如果ZF为1,指令会跳转到指定的标签或地址执行循环体,否则程序会跳出循环。

LOOPZ(Loop if Zero)指令与LOOPE类似,也是根据ZF的值来决定是否继续循环。如果ZF为1,指令会跳转到指定的标签或地址执行循环体,否则程序会跳出循环。
STC(Set Carry Flag):将进位标志设置为1。 示例代码:STC 作用:将进位标志设置为1,用于处理进位运算。

CLC(Clear Carry Flag):将进位标志清零。 示例代码:CLC 作用:将进位标志清零,用于处理不进位的运算。

CMC(Complement Carry Flag):将进位标志取反。 示例代码:CMC 作用:将进位标志取反,用于处理进位的取反操作。

STD(Set Direction Flag):将方向标志设置为1。 示例代码:STD 作用:将方向标志设置为1,用于指定字符串操作的方向为从高地址向低地址。

STI(Set Interrupt Flag):将中断标志设置为1。 示例代码:STI 作用:将中断标志设置为1,用于允许或禁止中断。

CLI(Clear Interrupt Flag):将中断标志清零。 示例代码:CLI 作用:将中断标志清零,用于禁止中断

伪指令

简介:为什么要有伪指令 伪指令我个人理解是他不存在只是为了标记这个指令而已

ORG (Origin):指定程序的起始地址。这个伪命令用于告诉汇编器程序应该从哪个内存地址开始加载。例如,ORG 100表示程序应该从内存地址100开始加载。

EQU (Equal):定义符号常量。这个伪命令用于给一个符号(通常是一个标签)定义一个常量值。例如,MAX_COUNT EQU 10表示将MAX_COUNT定义为常量10。

DB (Define Byte):定义字节数据。这个伪命令用于在程序中定义字节类型的数据。例如,DB 65表示在内存中存储一个字节,值为65。

DW (Define Word):定义字数据。这个伪命令用于在程序中定义字类型的数据。例如,DW 1000表示在内存中存储一个字,值为1000。

DS (Define Storage):定义存储空间。这个伪命令用于在程序中分配一定数量的存储空间,用于存储数据。例如,DS 10表示分配10个字节的存储空间。

END:指示程序结束。这个伪命令用于告诉汇编器程序的结束位置。对于一些汇编器,END命令后面可能还包括一些附加信息,如程序作者、版本号等。

TITLE:指定程序的标题。这个伪命令用于在汇编程序中添加一个标题或注释。例如,TITLE "My Assembly Program"表示给程序添加一个标题。

INCLUDE:包含外部文件。这个伪命令用于将另一个文件中的代码包含到当前的汇编程序中。例如,INCLUDE "myLibrary.asm"表示将myLibrary.asm文件中的代码包含到当前程序中。

MACRO:定义宏。这个伪命令用于定义一个宏,宏是一段可重用的代码片段。例如,可以使用DEFINE MACRO来定义一个简单的宏,然后在程序中通过使用CALL指令来调用它。

ENDIF:条件编译结束。这个伪命令用于标记条件编译的结束位置。它通常与IF或ELSE伪命令一起使用,用于定义条件编译的代码块。

比较符号> < =



JE (Jump if Equal)指令:当前面的比较结果为相等时跳转到指定目标地址。1 == 1 跳

JNE (Jump if Not Equal)指令:当前面的比较结果为不相等时跳转到指定目标地址。1 == 2 跳 

JG (Jump if Greater)指令:当前面的比较结果为大于时跳转到指定目标地址。 >

JGE (Jump if Greater or Equal)指令:当前面的比较结果为大于或等于时跳转到指定目标地址。>=

JL (Jump if Less)指令:当前面的比较结果为小于时跳转到指定目标地址。<

JLE (Jump if Less or Equal)指令:当前面的比较结果为小于或等于时跳转到指定目标地址。<=
JAE(Jump if Above or Equal):如果前一个操作结果大于或等于零,则跳转到指定的地址。它通常与无符号整数的比较和条件跳转一起使用。  数值 >= 0

JNB(Jump if Not Below):如果前一个操作结果不小于零,则跳转到指定的地址。它通常与无符号整数的比较和条件跳转一起使用。  > 0 

JB(Jump if Below):如果前一个操作结果小于零,则跳转到指定的地址。它通常与无符号整数的比较和条件跳转一起使用。  > 0

JMAE(Jump if Not Above or Equal):如果前一个操作结果不大于或等于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。  <= 0

JBE(Jump if Below or Equal):如果前一个操作结果小于或等于零,则跳转到指定的地址。它通常与无符号整数的比较和条件跳转一起使用。 >= 0

JNA(Jump if Not Above):如果前一个操作结果不大于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。 < 0


JNLE(Jump if Not Less or Equal):如果前一个操作结果不小于或等于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。

JGE(Jump if Greater or Equal):如果前一个操作结果大于或等于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。

JNL(Jump if Not Less):如果前一个操作结果不小于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。

JNGE(Jump if Not Greater or Equal):如果前一个操作结果不大于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。 

JNG(Jump if Not Greater):如果前一个操作结果不大于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。


JNGE(Jump if Not Less or Equal):如果前一个操作结果不小于或等于零,则跳转到指定的地址。它通常与有符号整数的比较和条件跳转一起使用。


JNZ(Jump if Not Zero):如果前一个操作结果不等于零,则跳转到指定的地址。它通常与条件跳转一起使用。数值 != 0




逻辑操作符

SHL 逻辑左移 
SAL 算术左移
SHR 逻辑右移
SAR 算术右移
ROL 循环左移
ROR 循环右移
RCL 通过进位的循环左移
RCR 通过进位的循环右移

操作符

OR | 或运算
2个1 则1     2个0则0 其余全1;
AND & 与运算  
2个1则只1 有0则都为0;
~ NOT 非运算
按位取反
^ XOR 异或 运算
不同则1 相同则0;
NAND 与非运算 有0则1, 全1则0;
XNOR 同或运算 相同则1, 不同则0;

串或符指令

以下是给出的指令作用的详细说明和示例代码:

  1. MOVS (Move String):将源操作数的内容复制到目的操作数。 示例代码:

    .data
    source db 1, 2, 3
    destination db 0, 0, 0
    
    .code
    mov esi, offset source
    mov edi, offset destination
    mov ecx, 3
    
    rep movsb  ; 将源操作数的内容复制到目的操作数
    
    ; 在此之后,destination中的内容为1, 2, 3
    

  2. CMPS (Compare String):比较源操作数和目的操作数的内容。 示例代码:

    .data
    source db 1, 2, 3
    destination db 1, 2, 4
    
    .code
    mov esi, offset source
    mov edi, offset destination
    mov ecx, 3
    
    rep cmpsb  ; 比较源操作数和目的操作数的内容
    
    ; 在此之后,ZF(零标志位)将被设置为0,因为源操作数和目的操作数的第三个元素不相等
    

  3. SCAS (Scan String):在字符串中扫描特定的值。 示例代码:

    .data
    source db 1, 2, 3
    
    .code
    mov edi, offset source
    mov eax, 2
    
    repne scasb  ; 在字符串中扫描值2
    
    ; 在此之后,ZF(零标志位)将被设置为1,因为找到了值2
    

  4. LOBS (Load String Byte):将字节加载到寄存器中。 示例代码:

    .data
    source db 42
    
    .code
    mov esi, offset source
    lodsb  ; 将源操作数的字节加载到AL寄存器中
    
    ; 在此之后,AL寄存器中的内容为42
    

  5. STOS (Store String):将寄存器的内容存储到目的操作数中。 示例代码:

    .data
    destination db 0, 0, 0
    value db 42
    
    .code
    mov edi, offset destination
    mov al, value
    
    mov ecx, 3
    rep stosb  ; 将AL寄存器的内容存储到目的操作数中
    
    ; 在此之后,destination中的内容为42, 42, 42
    

  6. STOSB (Store String Byte):将字节存储到目的操作数中。 示例代码:

    .data
    destination db 0, 0, 0
    
    .code
    mov edi, offset destination
    mov al, 42
    
    mov ecx, 3
    rep stosb  ; 将AL寄存器的字节存储到目的操作数中
    
    ; 在此之后,destination中的内容为42, 42, 42
    

  7. STOSW (Store String Word):将字存储到目的操作数中。 示例代码:

    .data
    destination dw 0, 0, 0
    
    .code
    mov edi, offset destination
    mov ax, 42
    
    mov ecx, 3
    rep stosw  ; 将AX寄存器中的字存储到目的操作数中
    
    ; 在此之后,destination中的内容为42, 42, 42
    

  8. STOSD (Store String Doubleword):将双字存储到目的操作数中。 示例代码:

    .data
    destination dd 0, 0, 0
    
    .code
    mov edi, offset destination
    mov eax, 42
    
    mov ecx, 3
    rep stosd  ; 将EAX寄存器中的双字存储到目的操作数中
    
    ; 在此之后,destination中的内容为42, 42, 42
    

指针/中断

指针
LES 传入目标指针装入FS
LFS 传入目标指针装入FS
LGS 传入目标指针装入GS
LSS 传入目标指针装入SS
中断
INT 中断
INTO 溢出中断
IRET 中断返回
WAIT 
NOP 空操作占个位
MIPS架构:WAIT(Wait For Interrupt),使用WAIT指令将CPU进入等待状态。 示例:WAIT

汇编指令

ESI

section .data
    source db "Hello, World!",0
    destination db 20 dup(0)

section .text
    global _start

_start:
    mov esi, source   ; 将源字符串的地址加载到ESI寄存器
    mov edi, destination   ; 将目标字符串的地址加载到EDI寄存器

copy_loop:
    mov al, [esi]     ; 将源字符串中的字符加载到AL寄存器
    mov [edi], al     ; 将AL寄存器中的字符存储到目标字符串中
    inc esi          ; 增加源字符串地址
    inc edi          ; 增加目标字符串地址
    cmp al, 0        ; 检查是否已到源字符串的结束
    jne copy_loop    ; 如果源字符串还未结束,继续循环复制

    ; 程序结束
    mov eax, 1       ; 退出系统调用号
    xor ebx, ebx     ; 返回状态码
    int 0x80

ZF 标志位 (相当于布尔值 )

HLT 暂停

如何实现HLT呢 默认c语言是没有的
创建一个文件
nasfunc.nas
[FORMAT "WCOFF"]  //制作文件模式
[BITS 32] // 制作32位机械语言

;文件信息
[FILE "naskfunc.nas"]  //源文件信息
        GLOBAL _io_hlt ;生成对象函数名
        [SECTION .text] ;告诉编译器引用这个文件才可以使用
        _io_hlt:   ;引用方法 void io_hlt(void)
                HLT
                RET

 

MOVSX 先扩展符号在移值

MOVZX 先初始化 在移值

JZ 判断 (等于c语言的 if )

MOV 移值指令(赋值)

XCHG 交换指令(位置 寄存器值 内存位置)
XLAT 字节表转换
OUT I/O端口输出
IN I/O端口输入
EQU   等于c语言 define

LEA 装入有效地址
LEA DX (类型)字符串;  把偏移地址存到DX
LDS
LDSSI (类型)字符串;把段地址:偏移到DS:SI

LAHF寄存器(Load AH from Flags)

8位的寄存器

用于将处理器的状态寄存器(FLAGS寄存器)中的标志位复制到AH寄存器的对应位

作用是将标志位的值传送给通用寄存器,以便于程序能够检测和处理相应的标志位。
section .data
    result db 0

section .text
    global _start

_start:
    ; 执行LAHF指令
    lahf

    ; 存储结果到result变量
    mov [result], ah

    ; 退出程序
    mov eax, 1
    xor ebx, ebx
    int 0x80
 

SAHF寄存器(Store AH into Flags)

于将AH寄存器的值复制到处理器的状态寄存器中的标志位

作用是将通用寄存器中保存的标志位的值传送给处理器的状态寄存器,以便于程序能够修改和处理相应的标志位
LOOP 循环指令
NEC 求反

CWD

16位指令将AX中的有符号数扩展到DX和AX中。具体来说,它将AX中的最高位(即符号位)复制到DX的所有位,从而在DX和AX中生成一个16位有符号数。

CBW

8位指令,用于将AL中的有符号数扩展到AX中。类似于CWD指令,它将AL中的最高位复制到AX的所有位,从而在AX中生成一个16位有符号数。

CWDE

16位指令,用于将AX中的有符号数扩展到EAX中。它通过将AX中的最高位复制到EAX的所有位来实现。

CDQ

32位指令,用于将EAX中的有符号数扩展到EDX和EAX中。类似于CWD指令,它将EAX中的最高位复制到EDX的所有位,从而在EDX和EAX中生成一个32位有符号数。

REP 指令(复制指令)
REP MOVSB:将字节从一个内存位置复制到另一个内存位置。
REP MOVSW:将字(16 位)从一个内存位置复制到另一个内存位置。
REP MOVSD:将双字(32 位)从一个内存位置复制到另一个内存位置。
REP STOSB:在内存中填充字节。
REP STOSW:在内存中填充字(16 位)。
REP STOSD:在内存中填充双字(32 位)

列子:
    mov ecx, 10 ; 设置要复制的字节数为 10
    mov esi, source ; 设置源地址
    mov edi, destination ; 设置目标地址
    rep movsb ; 重复执行 MOVSB 指令,将字节从源地址复制到目标地址
PROC 定义过程
ENDP 过程结束
.CODE

Main PROC
    ; 过程的代码逻辑

    MOV EAX, 0 ; 将EAX寄存器清零

    ; 过程的代码逻辑

    RET ; 返回到调用该过程的代码

Main ENDP

END Main

SEGMENT 定义段
ASSUME 建定段寄存器寻址
ENDS 段结束
END 结束程序
NOP 延迟程序
RET 返回程序

栈指令

push 入栈
pop 出栈
call 调用
lea 移地址
repstos 拷贝地址循环
and 
PUSHF 标志入栈
POPF 标志出栈
PUSHD 32位标志入栈 
POPD 32为标志出栈
A/*代表全部 按顺序来的
这里我设置变量
set 寄存器顺序(register) = {AX CX DX BX SP BP SI DI PI }*/

/*AD 代表扩展 按照顺序来的只不过是这样的
set 扩展寄存器顺序 = {EAX EDX EBX ESP EBP .....}*/
PUSHA:
把 register 按照顺序依仗次压栈

POPA
把 register 按照顺序依次弹出

PUSHAD
把扩展寄存器 按照顺序依次压栈

POPAD
把扩展寄存器 按照顺序依次弹出

组合

XADD 先交换在累加 (值永远在第一个寄存器中)
CMPXCHG 比较并交换

补充知识

标志位是一种用于标记CPU状态和操作结果的标志位。在汇编语言中,标志位是一组二进制位,用于记录和反映CPU运行状态和操作结果。

标志位常用的有以下几个:

1.进位标志位(Carry Flag,CF):记录运算结果的进位情况,用于处理大数相加或减法运算。

2.零标志位(Zero Flag,ZF):记录运算结果是否为零,用于判断条件跳转或循环结束条件。

3.符号标志位(Sign Flag,SF):记录运算结果的符号,用于判断运算结果是否为负数。

4.溢出标志位(Overflow Flag,OF):记录运算结果是否超出了机器数的表示范围,用于处理超出范围的运算结果。

5.奇偶标志位(Parity Flag,PF):记录运算结果中二进制位1的个数是否为偶数,用于处理奇偶校验。

汇编指令可以通过读取和修改标志位的值,实现根据不同的条件执行不同的操作,如条件跳转、循环控制、分支判断等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值