linux操作系统分析实验-从汇编代码理解存储程序计算机和函数调用堆栈框架在执行过程中所起的作用

实验内容

将一个简单的C程序汇编成ARM64汇编代码,并逐步分析程序的执行过程,深入理解存储程序计算机和函数调用堆栈框架在执行过程中所起的作用。

 

实验环境

Windows11

WSL Ubantu20.04.5 LTS

 

实验过程

首先可以使用vscode进行文件编辑:

Vscode可以和WSL(windows子系统)无缝衔接,使用vscode连接WSL十分方便。常规连接虚拟机需要通过插件配置ssh远程登陆,而连接WSL只需要在对应目录下输入一行代码 Code . 即可将WSL下当前目录在vscode中打开

 

详见 开始通过 WSL 使用 VS Code | Microsoft Learn

 

使用的C程序如下

 

WSL下安装交叉编译工具

sudo apt-get install gcc-aarch64-linux-gnu

 

建议执行前对apt进行换源

cd /etc/apt

sudo cp sources.list sources.list.bak

sudo vim sources.list

打开后输入源网站,以阿里源为例

deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

 

执行命令得到程序的汇编代码

gcc -S -o assembly_aarch64.s assembly.c

aarch64-linux-gnu-gcc -S -o assembly_aarch64.s assembly.c

其中带.的指令为ARM GNU伪汇编指令,分析时可以不看

 

汇编代码分析

Main中

stp  x29, x30, [sp, -16]!  //  *(sp-32) = x29(fp)和x30(lr); sp = sp - 32

mov x29, sp  // x29 = sp

建立被调用者堆栈框架

ldp  x29, x30, [sp], 16  //  x29和x30 = *(sp); sp = sp + 32

则是拆除被调用者对战框架

 

同样的,f中

sub  sp, sp, #16

为建立堆栈框架

add sp, sp, 16

为拆除

 

Main中剩余的两行

mov  w0, 3

bl  f

一行为指定函数调用的参数,一行为进行函数调用

Bl指令将pc中下一台条指令地址保存在lr(x30),并设置pc指向被调用函数的起始地址

arm64中,lr寄存器(一般为X30)保存跳转指令的目标位置,fp寄存器(一般为X29)为

栈底指针寄存器,sp为栈顶指针寄存器

 

函数调用时如果有参数,将参数写入对应寄存器(如w0)

将lr和fp寄存器的值保存在被调用者的栈顶位置,即sp指向的位置

同时移动sp,此时堆栈空间变为被调用者的

调用结束时移动sp还原堆栈,同时移动pc到lr指向的位置(如有必要,首先从栈顶取出lr的值)

 

posted @ 2023-03-13 19:41  skadfj  阅读(79)  评论(0)    收藏  举报