此汇编代码需要解释

2023-12-11

这是c代码:

void test_function(int a, int b, int c, int d) 
{
int flag;
char buffer[10];
flag = 31337;
buffer[0] = 'A';
}
int main() 
{
test_function(1, 2, 3, 4);
}

test_function 的组装:

Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret

End of assembler dump.
(gdb) print $ebp-12
$1 = (void *) 0xbffff7dc
(gdb) print $ebp-40
$2 = (void *) 0xbffff7c0
(gdb) x/16xw $esp
0xbffff7c0: (1)0x00000000 0x08049548 0xbffff7d8 0x08048249
0xbffff7d0: 0xb7f9f729 0xb7fd6ff4 0xbffff808 0x080483b9
0xbffff7e0: 0xb7fd6ff4 (2)0xbffff89c (3)0xbffff808 (4)0x0804838b
0xbffff7f0: (5)0x00000001 0x00000002 0x00000003 0x00000004

我对这些话题很陌生;因此,我的脑海中存在着一些问题。

  1. 我想汇编代码的前三行是序言。它推送 ebp,然后将 esp 复制到 ebt。但是,我不明白为什么 esp 在内存中返回 40 个字节。
  2. 它将31337放入ebp-12中,但为什么它正是ebp-12并且它代表标志的内存? 似乎没有,因为在底部,(2) 被指定为标志的内存。
  3. 在“x/16xw $esp”下面,左边不包含任何(数字)的其他内存是什么,因为带有数字的内存代表局部变量、参数和 sfp?

你的问题

It pushes ebp, then copies esp to ebt

ebt 是错误的,没有调用 ebt 的寄存器。应该是ebp。

push ebp

该命令用于在调用 test_function 函数之前保留堆栈底部。

mov ebp,esp
sub esp,0x28

该命令用于在 test_function 函数执行期间增加堆栈以分配新的内存块来存储值。并且栈增加的大小不是固定的,不会一直是0x28。该值由编译器计算,以确保大小合适。

mov DWORD PTR [ebp-12],0x7a69

对应flag=31337,flag地址等于ebp-12的值。地址由编译器分配。 DWORD对应于int。十六进制数0x7a69相当于十进制数31337。

And

mov BYTE PTR [ebp-40],0x41

与相同。十六进制数0x41相当于十进制数65。字母A的ASCII码的十进制值为十进制数65。BYTE对应于char。

下面的代码

(gdb) x/16xw $esp
0xbffff7c0: (1)0x00000000 0x08049548 0xbffff7d8 0x08048249
0xbffff7d0: 0xb7f9f729 0xb7fd6ff4 0xbffff808 0x080483b9
0xbffff7e0: 0xb7fd6ff4 (2)0xbffff89c (3)0xbffff808 (4)0x0804838b
0xbffff7f0: (5)0x00000001 0x00000002 0x00000003 0x00000004

如0xbffff7c0:左侧代码为地址,其值为0x00000000。所以 0xbffff7c4(0xbffff7c4 = 0xbffff7c0 + 4) 地址的值为 0x08049548,因为 0x00000000 占用 4 个字节。 0xbffff7c8地址的值为0xbffff7d8。 ....

我认为下面的汇编代码

Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret

可以转换下面的代码(@Peter Cordes 指出“leave”等于“mov esp,ebp”+“pop ebp”,请参见https://www.felixcloutier.com/x86/leave)

Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
                               mov esp,ebp   // here changed
                               pop ebp       // here changed
0x08048356 <test_function+18>: ret

局部变量存储在堆栈中。

这样我们就可以得到一张图,如下图所示:

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

此汇编代码需要解释 的相关文章

  • 如何使用 C# 打印 pdf

    我在 C 应用程序中使用 进程 打印 pdf 文件 但是我无法获取打印状态 我发现可以通过 System management 和 System printing 与打印机 队列进行交互 我做了很多尝试 但都出错了使用这两个命名空间但无法打
  • 以编程方式 Godaddy 发送的电子邮件不在“已发送邮件”文件夹中 C#.net

    我正在通过以下方式发送电子邮件ASP NET代码使用godaddy邮件服务器 邮件发送成功 但未存储在已发送邮件文件夹中 我正在使用下面的代码 SmtpClient client new SmtpClient client Host smt
  • 在两个 .cpp 文件之间定义全局变量 [重复]

    这个问题在这里已经有答案了 如何在 A cpp 和 B cpp 之间共享 全球化 bool 变量 其中它们都不包含其他 h 文件 他们有其他联合头文件 但彼此没有 我可以在这些共享标头中定义全局变量吗 Thanks 我可以在这些共享标头中定
  • C/C++ 中随机数生成器的实现[重复]

    这个问题在这里已经有答案了 我对 C 中随机数生成器的实现有点困惑 它也与 C 中的明显不同 如果我理解正确 对 srand seed 的调用会以某种方式初始化可通过 rand 访问的隐藏变量 种子 该变量又将函数指向预先生成的序列 例如例
  • 如何将 C++ 类包装在基于 C 的 dll 或基于 CLI 的 dll 中?

    我被告知将我用 C 编写的类导入到 dll 中 然后在 c 应用程序中使用该 dll 下列的本指南 https stackoverflow com questions 4555961 how to use a class in dll我创建
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机
  • C++ 模板参数类型推断

    我有一个这样的C 模板 template
  • Windows 程序如何临时更改其时区?

    我写了一个函数来返回time t与给定日期的午夜相对应的值 当给定日期没有午夜时 它返回最早可用的时间 例如 当埃及进入夏令时时 这种情况就可能发生 今年 时间更改于 4 月 29 日晚上午夜生效 因此时钟直接从 23 59 转到 01 0
  • 使用 Microsoft Graph 创建用户

    如何使用 Microsoft graph 创建用户 因为我在保存过程中遇到了权限失败的问题 我确实有几个问题 在图中调用创建用户 API 将在哪里创建用户 是在 Azure AD 还是其他地方 我尝试通过传递 json 和必需的标头来调用创
  • 为什么在 .net 中使用 Invoke on Controls? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么 NET不允许跨线程操作 https stackoverflow com questions 2896504 why net does not allow cross thread operat
  • 从存储过程返回 int 值并在 ASP.NET 代码中检查它以验证登录表单

    当我多次尝试但没有得到有效结果时 使此代码运行的真实顺序是什么 SQL存储过程的代码 set ANSI NULLS ON set QUOTED IDENTIFIER ON GO ALTER PROC dbo login proc usern
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • .NET 的 HttpWebResponse 是否会自动解压缩 GZiped 和 Deflated 响应?

    我正在尝试执行一个接受压缩响应的请求 var request HttpWebRequest HttpWebRequest Create requestUri request Headers Add HttpRequestHeader Acc
  • 停止 TcpListener 的正确方法

    我目前正在使用 TcpListener 来处理传入连接 每个连接都有一个线程用于处理通信 然后关闭该单个连接 代码如下 TcpListener listener new TcpListener IPAddress Any Port Syst
  • 使 C# 编译器相信执行将在成员返回后停止

    我认为目前这是不可能的 或者这是否是一个好主意 但这是我刚才正在考虑的事情 我使用 MSTest 对我的 C 项目进行单元测试 在我的一项测试中 我执行以下操作 MyClass instance try instance getValue
  • printf 参数不足

    我的问题是关于缺少参数的 printf 之后的行为 printf s blah blah d int integer was given as argument and not int written 我已经知道 如果格式参数不足 则行为是
  • 统一;随机物体移动[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在制作一款机器人战斗游戏 我希望敌人随机移动 然后有时会向敌人移动 我希望运动包含在其中的代码 else if avoid fal
  • Visual Studio 2015默认附加库

    当我在 VS 2015 中创建一个空项目时 它会自动将这些库放入 附加依赖项 中 kernel32 lib user32 lib gdi32 lib winspool lib comdlg32 lib advapi32 lib shell3
  • 编译器什么时候内联函数?

    在 C 中 函数仅在显式声明时才内联inline 或在头文件中定义 或者编译器是否允许内联函数 因为他们认为合适 The inline关键字实际上只是告诉链接器 或告诉编译器告诉链接器 同一函数的多个相同定义不是错误 如果您想在标头中定义函
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码

随机推荐