20242809《Linux内核原理与分析》第二周作业

刘政乔 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

引言

在现代计算机科学中,理解计算机的工作原理是至关重要的。本文将通过分析汇编代码的工作过程,特别是堆栈的变化,来探讨计算机是如何工作的。

实验环境与准备

在本次实验中,我们使用了以下环境和工具:

实验截图

总结

通过分析这个简单的C程序及其对应的汇编代码,我们可以看到计算机是如何通过堆栈管理函数调用和参数传递的。堆栈在函数调用过程中起到了关键作用,确保了每个函数都有自己的独立空间来存储局部变量和返回地址。

  • 操作系统:Ubuntu 20.04
  • 汇编语言:x86汇编
  • 编译器:NASM
  • 调试工具:GDB

    代码示例

    首先,我们有一个简单的C程序main.c

    // main.c
    int g(int x)
    {
        return x + 279;
    }
        
    int f(int x)
    {
        return g(x);
    }
        
    int main(void)
    {
        return f(3619) + 719;
    }
    

    使用以下命令将其编译为汇编代码:

    gcc -S -o main.s main.c -m32
    

    生成的汇编代码分析

    生成的汇编代码main.s如下所示(简化版):

    Assembly

        .file   "main.c"
        .text
        .globl  g
        .type   g, @function
    g:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        addl    $279, %eax
        popl    %ebp
        ret
        .globl  f
        .type   f, @function
    f:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        pushl   %eax
        call    g
        addl    $4, %esp
        popl    %ebp
        ret
        .globl  main
        .type   main, @function
    main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        movl    $3619, (%esp)
        call    f
        addl    $8, %esp
        addl    $719, %eax
        leave
        ret
    

    堆栈变化分析

    让我们逐步分析堆栈在执行过程中如何变化:

  • main函数开始执行

    • pushl %ebp:保存旧的基址指针。
    • movl %esp, %ebp:设置新的基址指针。
    • subl $8, %esp:为局部变量分配空间。
  • 调用f(3619)

    • movl $3619, (%esp):将参数3619压入堆栈。
    • call f:调用f函数,返回地址压入堆栈。
  • f函数执行

    • pushl %ebp:保存旧的基址指针。
    • movl %esp, %ebp:设置新的基址指针。
    • movl 8(%ebp), %eax:将参数加载到eax中。
    • pushl %eax:将参数压入堆栈。
    • call g:调用g函数,返回地址压入堆栈。
  • g函数执行

    • pushl %ebp:保存旧的基址指针。
    • movl %esp, %ebp:设置新的基址指针。
    • movl 8(%ebp), %eax:将参数加载到eax中。
    • addl $279, %eax:执行x + 279
    • popl %ebp:恢复旧的基址指针。
    • ret:返回调用点。
  • 返回到f函数

    • addl $4, %esp:清理堆栈。
    • popl %ebp:恢复旧的基址指针。
    • ret:返回调用点。
  • 返回到main函数

    • addl $719, %eax:执行f(3619) + 719
    • leave:恢复堆栈指针和基址指针。
    • ret:返回调用点。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值