汇编语言 指令

leave

在16位汇编下相当于:
mov sp,bp
pop bp
 
在32位汇编下相当于:
mov esp,ebp;//将ebp指向(ebp内部应当保存一个地址,所谓指向即这个地址对应的空间)的值赋给esp
pop ebp 
 
/* leave指令将EBP寄存器的内容复制到ESP寄存器中,
以释放分配给该过程的所有堆栈空间。然后,它从堆栈恢复EBP寄存器的旧值。*/
 
 
 
 
dword ptr []
取地址为[]的四字节数据

 

 

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:

  1. .data
  2. byteVal BYTE 10001111b
  3. .code
  4. movzx ax,byteVal ;AX = 0000000010001111b

下图展示了如何将源操作数进行全零扩展,并送入 16 位目的操作数。


下面例子的操作数是各种大小的寄存器:

  1. mov bx, 0A69Bh
  2. movzx eax, bx ;EAX = 0000A69Bh
  3. movzx edx, bl ;EDX = 0000009Bh
  4. movzx cx, bl ;CX = 009Bh

下面例子的源操作数是内存操作数,执行结果是一样的:

  1. .data
  2. byte1 BYTE 9Bh
  3. word1 WORD 0A69Bh
  4. .code
  5. movzx eax, word1 ;EAX = 0000A69Bh
  6. movzx edx, byte1 ;EDX = 0000009Bh
  7. movzx ex, byte1 ;CX = 009Bh

MOVSX 指令(进行符号扩展并传送)将源操作数内容复制到目的操作数,并把目的操作数符号扩展到 16 位或 32 位。这条指令只用于有符号整数,有三种不同的形式:

MOVSX reg32, reg/mem8
MOVSX reg32, reg/mem16
MOVSX reg16, reg/mem8

操作数进行符号扩展时,在目的操作数的全部扩展位上重复(复制)长度较小操作数的最高位。下面的例子是将二进制数 1000 1111b 进行符号扩展并传送到 AX:

  1. .data
  2. byteVal BYTE 10001111b
  3. .code
  4. 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就是存储着字符串的正确长度了。

posted @ 2020-09-24 10:25  KnowledgePorter  阅读(151)  评论(0)    收藏  举报