飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3657|回复: 3

delphi与汇编笔记(2)关于EBP寄存器的说明与使用

[复制链接]
  • TA的每日心情
    奋斗
    2017-4-20 22:12
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2008-5-1 23:41:47 | 显示全部楼层 |阅读模式
    原文请见:
       http://blog.csdn.net/suiyunonghen/archive/2007/11/21/1897142.aspx
       进几天一直在研究在delphi中使用汇编的问题。上回说了一点。今天再把我刚刚弄出来的一点东西写上来。
       EBP、ESP、BP和SP都称为指针寄存器,主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式。
       现在我们来说一说EBP:
       EBP是基址指针寄存器:一般用来确认堆栈帧的起始位置,也就是指向栈底。也就是说,一般上一个函数调用该函数之后的一个地址也就存放在EBP中(所以一般在进入函数的时候将ebp寄存器内容压栈,即保存其函数的上级调用函数的栈基地址,以便于以后返回调用)。
       比如,我们要实现点一个Form1上的按扭Button1实现弹出对话框。我们一般是
       procedure TForm1.Button1Click(Sender: TObject);
       var  ss: string;      
       begin
           ss := '不得闲BASM测试';
           showmessage(ss);
       end;
       那么换成汇编的写法如下:
       procedure TForm1.Button1Click(Sender: TObject);
       var  ss: string;      
       begin
           ss := '不得闲BASM测试';
          asm
              mov   eax,[ebp-$04]  
              call    showmessage
          end;
       end;   // 说明:Ebp通过上面我们知道应该是用来指定Button1Click过程的入口地址,将其减4用来空一点空间出来用来存放局部变量 ,则此时[ebp- 04]中存放的则是字符串 ss 的地址,所以此时 eax中存放的则是 'BASM测试'  的地址
    然后 Call Showmessage,调用Showmessage函数,而Delphi默认的调用方式是寄存器方式,其1,2,3个参数分别对应着EAX,EDX,ECX, 而 EAX中已经存放了我们的局部变量地址。该函数则获得了字符串参数。

    上面的是用在过程里面,直接使用赋值后的字符串的地址传递给Showmessage函数调用。下面我们使用另一个方法来使用局部变量:
      通过查看CPU View我们可以知道,在上面的字符串赋值过程的汇编代码如下:
        lea     eax, [ebp-$04]{这是留出一个空位,用来给局部变量中转使用}
        mov   edx, $2342342{这里是一个随机的值,也就是字符串指针的值}
       然后下面调用了一个系统函数LstrLAsg
       Call    LstrLAsg
       该函数将EDX指向的地址内容复制到EAX指向的地址中去。所以由此可见,Delphi中的字符串赋值是通过拷贝实现的。
       所以我们可以通过一个过程传递一个字符串地址值来得实现上面的方法,代码如下:
      procedure Test(prAddress: integer);
    asm
        mov    edx,  eax                          //先将prAddress地址值存入Edx,便于调用LstrLAsg函数
        lea      eax,  [ebp-$04]               //将使用一个局部变量周转,(偏移地址)
        Call    System.@LstrLAsg       //调用系统的LstrLAsg函数实现字串复制
        mov    eax,  [ebp-$04]               //将实际的局部变量地址传递给Eax让Showmessage调用
        Call    Showmessage              //调用Showmessage函数
    end;

    然后我们在ButtonClick中调用如下:
      procedure TForm1.Button1Click(Sender: TObject);
       var  ss: string;      
       begin
           ss := '不得闲BASM测试';
           Test(integer(ss));
       end;

    [ 本帖最后由 suiyunonghen 于 2008-5-4 19:40 编辑 ]
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-4-6 10:07
  • 签到天数: 23 天

    [LV.4]偶尔看看III

    发表于 2008-6-18 08:18:29 | 显示全部楼层
    这样的文章还是有意义的.
    PYG19周年生日快乐!
  • TA的每日心情

    2019-3-20 17:55
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2009-6-5 08:04:11 | 显示全部楼层
    好东西,多谢楼主的分享
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2022-6-7 22:07
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2009-7-1 14:15:41 | 显示全部楼层
    不错 了解了一点 继续学习把!
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表