汇编语言 指令
leave
在16位汇编下相当于:
mov sp,bp
pop bp
在32位汇编下相当于:
mov esp,ebp;
//将ebp指向(ebp内部应当保存一个地址,所谓指向即这个地址对应的空间)的值赋给esp
pop ebp
/* leave指令将EBP寄存器的内容复制到ESP寄存器中,
以释放分配给该过程的所有堆栈空间。然后,它从堆栈恢复EBP寄存器的旧值。*/
取地址为[]的四字节数据
cdq
CDQ 是一个让很多人感到困惑的指令。 这个指令把 EAX 的第 31 bit 复制到 EDX 的每一个 bit 上。 它大多出现在除法运算之前。它实际的作用只是把EDX的所有位都设成EAX最高位的值。也就是说,当EAX <80000000, EDX 为00000000;当EAX >= 80000000, EDX 则为FFFFFFFF。
例如 :
假设 EAX 是 FFFFFFFB (-5) ,它的第 31 bit (最左边) 是 1,
执行 CDQ 后, CDQ 把第 31 bit 复制至 EDX 所有 bit
EDX 变成 FFFFFFFF
这时候, EDX:EAX 变成 FFFFFFFF FFFFFFFB ,它是一个 64 bit 的大型数字,数值依旧是 -5。
备注:
EDX:EAX,这里表示EDX,EAX连用表示64位数
neg
将操作数(不管正负数)转化为二进制补码(按位取反加1)(这个操作等同于从0减去操作数)。操作数可以存放在通用寄存器,或者内存中。
影响的标志位
如果源操作数是0,CF将置为0;否则将被设为1,OF, SF, ZF, AF, 和 PF
标志位将根据结果设定。
sar与 shr
1、相同点:汇bai编语言中SAR和SHR指令都是右移指令,SAR是算数右du移指zhi令(daoshift arithmetic right),而SHR是逻辑右移指令(shift logical right)。
2、两者的在于SAR右移时保留操作数的符号,即用符号位来补足,而SHR右移时总是用0来补足。
例如10000000算数右移一位是11000000,而逻辑右移一位是01000000。
3、用法不同:
SAR功能是将操作数右移,符号位保持不变,可用于有符号数除法;
SHR功能是将操作数右移,原最低位移入进位标志CF,原最高位补0;可用于无符号数除法.
sal 与shl
sal(算术左移指令bai)和shl(逻辑左移指令)指令的寻址方式、du控制移位方式等都一样zhi,区别其实只有一处:
SAL算术移位指令在执行时,实际上把操作数看成有符号数进行移位,最高位符号位移入CF,但本身保持原值;其余位顺序左移,次高位被舍弃。
SHL逻辑移位指令在执行时,实际上把操作数看成无符号数进行移位,所有位顺序左移,最高位移入CF。
movsx 和movzx
MOVZX 指令(进行全零扩展并传送)将源操作数复制到目的操作数,并把目的操作数 0 扩展到 16 位或 32 位。这条指令只用于无符号整数,有三种不同的形式:
MOVZX reg32,reg/mem8
MOVZX reg32,reg/mem16
MOVZX reg16,reg/mem8
在三种形式中,第一个操作数(寄存器)是目的操作数,第二个操作数是源操作数。注意,源操作数不能是常数。下例将二进制数 1000 1111 进行全零扩展并传送到 AX:
- .data
- byteVal BYTE 10001111b
- .code
- movzx ax,byteVal ;AX = 0000000010001111b
下图展示了如何将源操作数进行全零扩展,并送入 16 位目的操作数。

下面例子的操作数是各种大小的寄存器:
- mov bx, 0A69Bh
- movzx eax, bx ;EAX = 0000A69Bh
- movzx edx, bl ;EDX = 0000009Bh
- movzx cx, bl ;CX = 009Bh
下面例子的源操作数是内存操作数,执行结果是一样的:
- .data
- byte1 BYTE 9Bh
- word1 WORD 0A69Bh
- .code
- movzx eax, word1 ;EAX = 0000A69Bh
- movzx edx, byte1 ;EDX = 0000009Bh
- movzx ex, byte1 ;CX = 009Bh
MOVSX 指令(进行符号扩展并传送)将源操作数内容复制到目的操作数,并把目的操作数符号扩展到 16 位或 32 位。这条指令只用于有符号整数,有三种不同的形式:
MOVSX reg32, reg/mem8
MOVSX reg32, reg/mem16
MOVSX reg16, reg/mem8
操作数进行符号扩展时,在目的操作数的全部扩展位上重复(复制)长度较小操作数的最高位。下面的例子是将二进制数 1000 1111b 进行符号扩展并传送到 AX:
- .data
- byteVal BYTE 10001111b
- .code
- movsx ax,byteVal ;AX = 1111111110001111b
如下图所示,复制最低 8 位,同时,将源操作数的最高位复制到目的操作数高 8 位的每一位上。

如果一个十六进制常数的最大有效数字大于 7,那么它的最高位等于 1。如下例所示,传送到 BX 的十六进制数值为 A69B,因此,数字“A”就意味着最高位是 1。(A69B 前面的 0 是一种方便的表示法,用于防止汇编器将常数误认为标识符。)
repne scasb
scasb 来判断 al数据是否在edi中,配合repne来使用(当ECX不等于0 且ZF=0重复执行字符串指令时继续遍历)。
ax/al 搜索数据
es:di 目标串
cx 串长度
df 方向标志
该指令常用来判断字符串的长度。
其思路是将ecx置为-1(计数器),eax置为0(字符串结尾),之后每扫描一个ecx会再次减少1,当edi中找到0时其会终止,
此时ecx存储的是长度的负数,之后将 not ecx 来获取其长度,然后dec ecx (因为从1开始计数并非0开始计数),之后ecx就是存储着字符串的正确长度了。