BASM学习心得 (加法)

本文通过具体的Pascal程序示例,深入剖析了程序结构、函数实现方式及内存栈的操作原理。介绍了如何使用Pascal语言编写加法运算函数,并演示了参数传递、栈内存读取等关键技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

program Test1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function Add1(X,Y,Z,A,B,C:Integer):Integer;
begin
 Result := X+Y+Z+A+B+C;
end;

function Add(X,Y:Integer):Integer;
asm
  add     eax, edx
  mov     ebx, eax
end;

var
Result : Integer;
begin
  Result := Add1(13,12,31,41,51,61);
  Writeln(Result);

  Result := Add(12347,12374);
  Writeln(Result);

  Result := 4;
  Inc(Result,9);

  Writeln(Result);
  readln;
end.

Test1.dpr.22: Result := Add1(13,12,31,41,51,61);
00408805 6A29                      push $29//压入
00408807 6A33                      push $33//压入
00408809 6A3D                     push $3d//压入  当参数超过3个后  编译器会压入参数到栈
0040880B B91F000000       mov ecx,$0000001f
00408810 BA0C000000       mov edx,$0000000c
00408815 B80D000000       mov eax,$0000000d
0040881A E845FFFFFF        call Add1//调用ADD1
0040881F 8BD8                     mov ebx,eax
Test1.dpr.23: Writeln(Result);
00408821 A104934000        mov eax,[$00409304]
00408826 8BD3             mov edx,ebx
00408828 E80FA9FFFF       call @Write0Long
0040882D E856A9FFFF       call @WriteLn
00408832 E871A1FFFF       call @_IOTest
Test1.dpr.25: Result := Add(12347,12374);
00408837 BA56300000       mov edx,$00003056
0040883C B83B300000      mov eax,$0000303b
00408841 E836FFFFFF       call Add
00408846 8BD8                    mov ebx,eax
Test1.dpr.26: Writeln(Result);
00408848 A104934000       mov eax,[$00409304]
0040884D 8BD3                   mov edx,ebx
0040884F E8E8A8FFFF      call @Write0Long
00408854 E82FA9FFFF      call @WriteLn
00408859 E84AA1FFFF      call @_IOTest
Test1.dpr.28: Result := 4;
0040885E BB04000000      mov ebx,$00000004
Test1.dpr.29: Inc(Result,9);
00408863 83C309               add ebx,$09
Test1.dpr.31: Writeln(Result);
00408866 A104934000       mov eax,[$00409304]
0040886B 8BD3                    mov edx,ebx
0040886D E8CAA8FFFF      call @Write0Long
00408872 E811A9FFFF       call @WriteLn
00408877 E82CA1FFFF       call @_IOTest
Test1.dpr.32: readln;
0040887C A170934000       mov eax,[$00409370]
00408881 E8F6A5FFFF       call @ReadLn
00408886 E81DA1FFFF       call @_IOTest


Test1.dpr.9: begin
00408764 55               push ebp   //做标志栈,以后会对地址偏移量进行操作
00408765 8BEC             mov ebp,esp//把esp栈地址值压入EBP进行操作
Test1.dpr.10: Result := X+Y+Z+A+B+C;
00408767 03D0               add edx,eax
00408769 03CA                add ecx,edx
0040876B 034D10           add ecx,[ebp+$10]//(基地址+偏移量)
0040876E 034D0C          add ecx,[ebp+$0c]//(同上)
00408771 034D08           add ecx,[ebp+$08]
00408774 8BC1                mov eax,ecx//结果存到 eax
Test1.dpr.11: end;
00408776 5D                     pop ebp//ebp地址为034D08,直接从这个位置弹栈,清理数据
00408777 C20C00           ret $000c
0040877A 8BC0                mov eax,eax
Test1.dpr.15: add              eax, edx
0040877C 01D0                add eax,edx
Test1.dpr.16: mov              ebx, eax
0040877E 89C3                 mov ebx,eax
Test1.dpr.17: end;
00408780 C3                    ret
00408781 8D4000           lea eax,[eax+$00]
00408784 55                     push ebp
00408785 8BEC               mov ebp,esp
00408787 33C0                xor eax,eax
00408789 55                     push ebp
0040878A 68A3874000   push $004087a3 

===================================
为了验证整型读栈的方法
写了一个函数做
在函数执行前编译器已经为我们做了一个push ebp;
这样就是压入了16位,我们就可以通过+16位来读刚刚压入的4位的数据。
function Add2(X,Y,Z,A,B,C:Integer):Integer;
asm
  mov  ebx,[ebp+$10]
  mov  eax,[ebp+$10-$04]
  mov  ecx,[ebp+$10-$08]
  mov  eax,ebx
end;
ebx中显示的A
EAX中显示的B
ECX中显示的C

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值