win32汇编问题指令

一、关于REP/REPE/REPZ/REPNE/REPNZ

     按计数寄存器 ((E)CX) 中指定的次数重复执行字符串指令,或是重复到 ZF 标志不再满足指定的条件。REP(重复)、REPE(相等时重复)、REPNE(不相等时重复)、REPZ(为零时重复)及 REPNZ(不为零时重复)助记符都是可以添加到一些字符串指令中的前缀。REP 前缀可以添加到 INS、OUTS、MOVS、LODS 及 STOS 指令,REPE、REPNE、REPZ 及 REPNZ 前缀可以添加到 CMPS 与 SCAS 指令。(REPZ 与 REPNZ 前缀分别是 REPE 与 REPNE 前缀的同义形式)。同非字符串指令一起使用时,REP 前缀的行为未定义。

REP 前缀一次只能应用于一条字符串指令。要重复指令块,请使用 LOOP 指令或其它循环结构。

所有这些重复前缀都会使关联的指令重复执行,直到寄存器 (E)CX 中的计数递减到 0(请参阅下表)。(如果当前地址大小属性为 32,则将寄存器 ECX 用作计数器;如果大小属性为 16,则将 CX 寄存器用作计数器)。在每次迭代之后,REPE、REPNE、REPZ 及 REPNZ 前缀还会检查 ZF 标志的状态,如果 ZF 标志未处于指定的状态,则终止重复循环。同时测试两个终止条件时,终止重复的原因可以通过使用 JECXZ 指令来测试 (E)CX 寄存器进行确定,也可以通过使用 JZ、JNZ 及 JNE 指令来测试 ZF 标志进行确定。

重复前缀 终止条件1 终止条件2

REP

ECX=0

REPE/REPZ

ECX=0

ZF=0

REPNE/REPNZ

ECX=0

ZF=1

使用 REPE/REPZ 与 REPNE/REPNZ 前缀时,由于 CMPS 与 SCAS 指令都会根据它们的比较结果设置 ZF 标志,因此 ZF 标志不需要初始化。

正在重复的字符串操作可以因异常或中断而暂停。发生这种情况时,将保存寄存器的状态,以便从异常或中断处理程序返回时,字符串操作能够恢复。源寄存器与目标寄存器指向下一个要操作的字符串元素,EIP 寄存器指向字符串指令,ECX 寄存器保存的是上一次成功迭代指令之后的值。通过此种机制,就可以执行很长的字符串操作,而不会影响系统的中断响应时间。

在执行以 REPE 或 REPNE 为前缀的 CMPS 或 SCAS 指令期间,如果发生错误,EFLAGS 值还原为指令执行之前的状态。由于 SCAS 与 CMPS 指令不会将 EFLAGS 用作输入,因此,处理器可以在页错误处理程序完成之后恢复执行指令。

谨慎使用 REP INS 与 REP OUTS 指令。并非所有的 I/O 端口都可以处理这些指令的执行速率。

初始化大块内存最快的方法是使用 REP STOS 指令。

 示例一:在字符串中查找字符

cld //从低地址到高地址方向 
lea edi, lpszName //edi指向目标字符串首地址 (00402068)="*.exe"
mov al,'x' //要查找值放入al中 
mov ecx,5 //重复查找次数
repne scasb //在edi所指字符串中查找al值,若不等将继续查找,直到(ecx)=0

REPNE执行的操作:
1)如(ecx)=0时退出,否则往下执行
2)(ecx)=(ecx)-1
3)执行其后的串指令
4)重复1)~3)
上述程序段执行结果:(edi)=0040206c   (ecx)=1

 示例二:两个字符串比较

cld //从低地址到高地址方向 
lea edi, lpszSrc //edi指向目标字符串首地址 (00402060)="c:\windows"
lea esi, lpszDes //edi指向目标字符串首地址 (00402090)="c:\windows" 
mov ecx,11 //重复查找次数
repz cmpsb //如果相等则继续比较,直到源目字符不等或(ecx)=0才结束 
.if ZERO? //如果条件满足,表示两个字符串完全相等
...          
.endif//重复查找次数 
上述程序段执行结果:(edi)=0040206B   (edi)=0040209B  (ecx)=0  ZF=1

二、关于mul div imul idiv

MUL: 无符号乘


;影响 OF、CF 标志位
;指令格式:
;MUL r/m  ;参数是乘数

;如果参数是 r8/m8,   将把  AL 做乘数, 结果放在 AX
;如果参数是 r16/m16, 将把  AX 做乘数, 结果放在 EAX
;如果参数是 r32/m32, 将把 EAX 做乘数, 结果放在 EDX:EAX
示例一: 8 位
mov al, 0FFh mov cl, 8 mul cl 执行结果:(ax)=07F8h   示例二: 16 位 mov ax, 0FFFFh
mov cx, 8
mul cx
执行结果:(dx)=0007h (ax)=0FFF8h   示例三: 32 位   mov eax, 0FFFFFFFFh
  mov ecx, 8   mul ecx   执行结果: (edx)=00000007h (eax)=0FFFFFFF8h

IMUL: 有符号乘
;影响 OF、CF 标志位
;第一种指令格式:
;IMUL r/m  ;单操作数

;如果参数是 r8/m8,   将把  AL 做乘数, 结果放在 AX
;如果参数是 r16/m16, 将把  AX 做乘数, 结果放在 EAX
;如果参数是 r32/m32, 将把 EAX 做乘数, 结果放在 EDX:EAX

;以上这些都是和 MUL 一样的, 只是运算结果有时一样、有时不一样.

;IMUL 还有另外两种指令格式:
;IMUL r16/r32, r16/r32/m16/m32/i  ;双操作数, (1)*(2) -> (1)
;IMUL r16/r32, r16/r32/m16/m32, i ;三操作数, (2)*(3) -> (1)

;其中常数 i 的位数可以 <= 但不能 > 其他操作数

    示例一:8 位   
mov al, 0FFh
mov cl, 8 imul cl
执行结果:(ax)=0FFF8h   示例二:16 位   mov ax, 0FFFFh
mov cx, 8
  imul cx
  执行结果:(dx)=0FFFFh (ax)=0FFF8h   示例三:32 位   mov eax, 0FFFFFFFFh
mov ecx, 8
  imul ecx   执行结果:(edx)=0FFFFFFFFh (eax)=0FFFFFFF8h 示例四:;IMUL 两个操作数   mov eax, 7
mov ecx, 8   imul eax, 8   执行结果:(eax)=56   示例五:IMUL 三个操作数   mov ecx, 8
imul eax, val, 9   执行结果:(eax)=72

MUL 与 IMUL 结果的一致和不一致:

示例六:如果操作数都没有符号位, 结果一致   mov al, 7Fh
mov cl, 7fh
  mul cl   执行结果: (ax)=3F01h     mov al, 7Fh
mov cl, 7fh   imul cl   执行结果: (ax)=3F01h   示例七:如果操作数的其中之一有符号位, 结果不一致   mov al, 80h
mov cl, 7fh   mul cl   执行结果: (ax)=3F80     mov al, 80h
mov cl, 7fh   imul cl   执行结果: (ax)=0C080h   示例八:如果操作数都有符号位, 结果也一致   mov cl, 80h   mov al, 80h   mul cl   执行结果: (ax)=4000h     mov al, 80h
mov cl, 80h
  imul cl   执行结果: (ax)=4000h


DIV、IDIV: 无符号除、有符号除


;它们没有定义对 EFLAGS 的影响
;它们的指令格式:
;DIV r/m  ;参数是除数

;如果参数是 r8/m8,   将把 AX      做被除数; 商 -> AL,  余数 -> AH
;如果参数是 r16/m16, 将把 DX:AX   做被除数; 商 -> AX,  余数 -> DX
;如果参数是 r32/m32, 将把 EDX:EAX 做被除数; 商 -> EAX, 余数 -> EDX
    示例一:除数是 8 位
     mov ax, 17   ;被除数
     mov cl, 3    ;除数
     div cl
     执行结果: (al)=5 --商    (ah)=2 --余数
    
     示例二:除数是 16 位
     mov dx, 0    ;
     mov ax, 17   ;dx:ax 是被除数
     mov cx, 3    ;cx    是除数
     div cx
     执行结果: (ax)=5 --商  (dx)=2 --余数
    
      示例三:除数是 32 位
      mov edx, 0   ;
      mov eax, 17  ;edx:eax 是被除数
      mov ecx, 3   ;ecx     是除数
      div ecx
      执行结果: (eax)=5 --商 (edx0=2 --余数
;IDIV 测试

     示例一:除数是 8 位
     mov al, -17   
     cbw          ;ax 是被除数
     mov cl, 3    ;除数
     idiv cl
     执行结果: (al)=-5 --商    (ah)=-2 --余数
    
     示例二:除数是 16 位
     mov ax, -17   
     cwd          ;dx:ax 是被除数
     mov cx, 3    ;cx    是除数
     idiv cx
     执行结果: (ax)=-5 --商 (dx)=-2 --余数
    
     示例三:除数是 32 位
     mov eax, -17  
     cdq          ;edx:eax 是被除数
     mov ecx, 3   ;ecx     是除数
     idiv ecx
     执行结果: (eax)=-5 --商   (edx)=-2 --余数
原文地址:https://www.cnblogs.com/guanlaiy/p/2507267.html