rep、repe、repne、repz、repnz
rep :ecx=0结束
repe:ecx=0、ZF=1 ZF=0时重复
repne:ecx=0、ZF=0 ZF=1时不重复
串操作指令
STD:执行后DF=1 (负方向) set direction flag
CLD:执行后DF=0(正方向)
ds:edi
ss:esp
其他默认是ds
代码段cs
stos
stos es:edi 把eax的值中的四个字节写到edi中,如果DF=0,此时还会edi+4
mov ecx ,0x30
mov eax, 0xcccccccch
rep stos ds:edi
这些代码表示循环给edi这个地址开始cccccccc依次填充0x30次
scas
repe scas 扫描与指定字符不同的字符串(因为不同时会直接结束扫描)
repne scas 扫描与指定字符相同的字符串 (因为相同时会直接退出)
裸函数
基本结构:
左边:默认是cdecl
#include<iostream>
_declspec(naked) int MyStrlen(char* str)
{
_asm ret
}
int main()
{
char szString[] = "hello";
MyStrlen(szString);
std::cout << "hello";
return 0;
}
右边:改成stdcall
#include<iostream>
_declspec(naked) int _stdcall MyStrlen(char* str)
{
_asm ret
}
int main()
{
char szString[] = "hello";
MyStrlen(szString);
std::cout << "hello";
return 0;
}
用裸函数实现strlen、strcmp、memset、memcpy
参考汇编代码:
.386
.model FLAT,STDCALL
option casemap:none
include msvcrt.inc
includelib msvcrt.lib
.data
szStringFormat db 10 dup(0)
.code
_myStrlen proto :dword
_myMemset proto :DWORD,:BYTE,:DWORD
_myStrcpy proto :DWORD,:DWORD
_myStrcmp proto :DWORD,:DWORD
_myMemset proc szDestString:DWORD,szFillByte:BYTE,dwlen:DWORD
mov edi,szDestString
mov al,szFillByte
mov ecx,dwlen
rep stosb
ret
_myMemset endp
_myStrlen proc szSrcString:DWORD
mov edi,[ebp+8]
mov al,0
mov ecx,0fffffffh
repne scasb
not ecx
mov eax,ecx
ret
_myStrlen endp
_myStrcpy proc szDestString:DWORD,szSrcString:DWORD
mov eax,szSrcString
push eax
call _myStrlen
mov ecx,eax
mov edi,szDestString
mov esi,szSrcString
rep movsb
ret
_myStrcpy endp
_myStrcmp proc szDestString:DWORD,szSrcString:DWORD
mov ecx,0fffffffh
mov esi,szSrcString
mov edi,szDestString
repne cmpsb
not ecx
mov eax,ecx
ret
_myStrcmp endp
main proc
LOCAL szStrl[20]:BYTE
LOCAL dwlen:DWORD
;memset(szStrl,0xcc,dwlen)
push 20
push 0cch
lea eax,szStrl
push eax
call _myMemset
;scanf("%S",szStrl)
lea eax,szStrl
push eax
push offset szStringFormat
call crt_scanf
;dwlen=strlen(strl)
lea eax,szStrl
push eax
call _myStrlen
;strcpy(szStrl,)
lea eax,szStrl
push eax
call _myStrcpy
;strcmp
lea eax,szStrl
push eax
call _myStrcmp
ret
main endp
entry:
call main
ret
end entry
裸函数实现:
#include<iostream>
#include <string.h>
#include <memory.h>
//1. memset(char* dest,int val,int len)
_declspec(naked) void MyMemset(char* dest, int val, int len)
{
_asm
{
push ebp
mov ebp,esp
push eax
push ecx
push edi
mov eax,val
mov ecx,len
mov edi,dest
rep stos edi
pop eax
pop ecx
pop edi
mov esp,ebp
pop ebp
}
}
//2. memcpy(char* dest, char* src, int len)
_declspec(naked) void MyMemcpy(char* dest, char* src, int len)
{
_asm
{
push ebp
mov ebp, esp
push edi
push esi
push ecx
mov edi,dest
mov esi,src
mov ecx,len
rep movsb edi,esi
pop ecx
pop esi
pop edi
mov esp, ebp
pop ebp
}
}
//3. strcmp(char* dest,char* src)
_declspec(naked) void MyStrcmp(char* dest, char* src)
{
_asm
{
push ebp
mov ebp, esp
push edi
push esi
mov edi,dest
mov esi,src
cmps edi,esi
pop esi
pop edi
mov esp, ebp
pop ebp
}
}
//4. int strlen(char* str)
_declspec(naked) int MyStrlen(char* str)
{
_asm
{
push ebp
mov ebp, esp
mov esp, ebp
pop ebp
}
}
int main()
{
char szString[] = "hello";
MyStrlen(szString);
std::cout << "hello";
return 0;
}