pmtest8.asm中lib.inc中MemCpy代码的理解

PagingDemo:
  mov ax, cs
 mov ds, ax
 mov ax, SelectorFlatRW       ;这应该是selectorFlatRW所对应的段描述符的首地址,参见pmtest7.asm
 mov es, ax

 push LenFoo          ;0x0000001c                    sp:0x000001f7
 push OffsetFoo       ;0x000001a0                   sp:0x000001f3
 push ProcFoo          ;ProcFoo equ 00401000h   sp:0x000001ef

 call MemCpy       ;前面几个push是MemCpy的参数,sp:0x000001eb,call会由系统自动压入参数,所以前面的sp要加4。

                         ;这段call的功能是把程序拷贝到ProcFoo处

; ------------------------------------------------------------------------
; 内存拷贝,仿 memcpy
; ------------------------------------------------------------------------
; void* MemCpy(void* es:pDest, void* ds:pSrc, int iSize);
; ------------------------------------------------------------------------
MemCpy:
 push ebp                    ;sp:0x000001e7 (这是因为call的参数占有了0x000001eb的堆栈) ebp=0x00000000
 mov ebp, esp              ;ebp=esp=0x000001e7

 push esi                    ; sp:0x000001e3 ,bp:0x000001e7        
 push edi                    ; sp:0xooooo1df ,bp:0x000001e7
 push ecx                    ; sp:0x000001db, bp:0x000001e7  ;为什么要用bp呢,这是因为sp在不断变化中,不适合作为读取指针

 mov edi, [ebp + 8] ; Destination    ;ebp+8=0x000001ef,指向ProcFoo,值为:00401000h            (见pmtest8.asm,319行)
 mov esi, [ebp + 12] ; Source         ;ebp+12=0x000001f3,指向OffsetFoo,值为:0x000001a0
 mov ecx, [ebp + 16] ; Counter       ;ebp+16=0x000001f7,指向LenFoo,值为:0x0000001c
.1:
 cmp ecx, 0  ; 判断计数器
 jz .2  ; 计数器为零时跳出

 mov al, [ds:esi]  ; ┓            ;ds等于cs (见pmtest8.asm,312行)           
 inc esi   ; ┃
     ; ┣ 逐字节移动
 mov byte [es:edi], al ; ┃       ;es等于selectorFlatRW所对应的段描述符的首地址(见pmtest8.asm,314行)
 inc edi   ; ┛                

 dec ecx  ; 计数器减一              ;这段程序的功能是把cs:OffsetFoo的程序拷贝到selectorFLatRW段:ProcFoo的地方。 
 jmp .1  ; 循环                        ;selectorFlatRW段首地址为0,所以就是拷贝到ProcFoo的地方,即00401000h处         
.2:                                
 mov eax, [ebp + 8] ; 返回值             ;eax=00401000h

 pop ecx                                 ;sp:0x000001df
 pop edi                                  ;sp:0x000001e3
 pop esi                                  ;sp:0x000001e7
 mov esp, ebp                         ;ebp=0x000001e7,esp=ebp,esp=0x000001e7
 pop ebp                                 ;sp:0x000001eb,ebp=0x00000000

 ret   ; 函数结束,返回             ;sp:0x000001ef
; MemCpy 结束-------------------------------------------------------------

posted on 2011-05-09 10:04  wanghj_dz  阅读(571)  评论(0编辑  收藏  举报

导航