一个底层w32汇编的小例子,演示 原创

主程序  结果见上图

.386
.model flat,stdcall
option casemap:none

include <windows.inc>
include <user32.inc>
includelib <user32.lib>
include <kernel32.inc>
includelib <kernel32.lib>

.code
start:

call test2


test2 proc
    local @loc1:dword,@loc2:word
    local @loc3:byte

    mov eax,@loc1
    mov ax,@loc2
    mov al,@loc3

    leave
    ret
 test2 endp



end start

 

反汇编后内存如下:

 我们经过分析发现:

主程序的地址是call 处的那个

子程序过程;

1.保护现场  入栈  

2.执行程序

3.返回断点  出栈

因为根据局部变量(包括函数形参)入堆栈的原理,我们发现,要先保存ebp这个寄存器(因为访问堆栈就是用的这个寄存器,esp只是用来标识堆栈栈顶位置的)

push ebp                ; 把原来ebp寄存器的值保存起来;
mov ebp,esp             ; 把esp寄存器的值复制到ebp寄存器中,供存取局部变量时做指针用;
add esp,FFFFFFF8        ; 在堆栈中预留(注意是预留,局部变量用完自动出栈,所以还要把esp的值重新赋值回来)出空间(即重新设置堆栈指针),由于堆栈是向下增长,所以要把esp加上一个负值。-8不是-7,因为dword访问内存更快
一条leave指令就实现了mov esp,ebp和pop ebp两条指令的功能。
esp用完要返回初始值,因为局部变量自动出栈。

.386
.model flat,stdcall
option casemap:none

include <windows.inc>
include <user32.inc>
includelib <user32.lib>
include <kernel32.inc>
includelib <kernel32.lib>

.code
start:

call test2


test2 proc
    local @loc1:dword,@loc2:word
    local @loc3:byte

    mov eax,@loc1
    mov ax,@loc2
    mov al,@loc3

    leave
    ret
 test2 endp



end start

原文地址:https://www.cnblogs.com/nanfengnan/p/13897664.html