栈是构建底层运行的基础,鸿蒙用栈方式递减满栈(FD)

    搜索 @note_pic 可查看绘制的全部字符图
    搜索 @note_why 是尚未看明白的地方,有看明白的,请Pull Request完善
    搜索 @note_thinking 是一些的思考和建议
    搜索 @note_#if0 是由第三方项目提供不在内核源码中定义的极为重要结构体,为方便理解而添加的。
    搜索 @note_good 是给源码点赞的地方
上级 9f6bcd92
......@@ -68,6 +68,8 @@
- **[鸿蒙源码分析系列(总目录) | 持续更新中... 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4626852)**
* **[|- 鸿蒙内核源码分析(汇编语言篇) | 栈是构建底层运行的基础 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/112534331) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4893388)**
* **[|- 鸿蒙内核源码分析(位图管理篇) | 为何进程和线程都是32个优先级? 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/112394982) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4888467)**
* **[|- 鸿蒙内核源码分析(源码结构篇) | 内核500问你能答对多少? 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/111938348) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4869137)**
......
......@@ -63,6 +63,40 @@ ARM的指令系统中关于栈指令的内容比较容易引起迷惑,这是
参考
https://www.cnblogs.com/fanzhidongyzby/p/5250116.html
用栈方式图 @note_pic
-----------------<------------------- 高地址 函数 A
| PC | |
|---------------| | ||
| LR | | ||
|---------------| | ||
| SP | | ||
|---------------| | \/
| FP | |
|---------------| |
| 参数1 | |
|---------------| |
| 参数2 | |
|---------------| |
| 变量1 | |
|---------------|<----------| | 函数A调用B
| PC | | |
|---------------| | |
| LR | | |
|---------------| | |
| SP |-----------| |
|---------------| |
| FP |-------------------|
|---------------|
| 参数1 |
|---------------|
| 参数2 |
|---------------|
| 变量1 |
|---------------|<------SP
| 变量2 |
|---------------|
|---------------| 低地址
******************************************************************************/
#ifdef LOSCFG_KERNEL_SMP_LOCKDEP
.extern OsLockDepCheckOut/*使用外部定义的函数*/
......
git add -A
git commit -m '鸿蒙用栈方式为:递减满栈(FD), 栈的操作指令为:STMFD,LDMFD
git commit -m '栈是构建底层运行的基础,鸿蒙用栈方式递减满栈(FD)
搜索 @note_pic 可查看绘制的全部字符图
搜索 @note_why 是尚未看明白的地方,有看明白的,请Pull Request完善
搜索 @note_thinking 是一些的思考和建议
......
//armv7-a clang (trunk)
#include <stdio.h>
int fp(int b)
{
int a = 1;
return a+b;
}
int main()
{
int sum = 0;
for(int a = 0;a < 100; a++){
sum = sum + fp(a);
}
return sum;
}
\ No newline at end of file
//编译器: armv7-a clang (trunk)
fp(int):
sub sp, sp, #8 @sp减去8,相当于只占用2个栈空间完成计算
str r0, [sp, #4] @先保存参数值,放在SP+4,此时r0中存放的是参数
mov r0, #1 @r0=1
str r0, [sp] @再把1也保存在SP的位置
ldr r0, [sp] @SP的值给R0
ldr r1, [sp, #4] @SP+4的值给R1
add r0, r0, r1 @得出计算结果给R0保存,返回值的工作一直是交给R0
add sp, sp, #8 @函数执行完了要跳回调用函数的SP位置
bx lr @子程序返回
main:
push {r11, lr} @r11(fp) ,lr 入栈
mov r11, sp @r11用于保存sp,函数栈开始位置
sub sp, sp, #16 @main函数将只占用4个栈空间完成计算
mov r0, #0 @初始化r0
str r0, [r11, #-4] @作用是保存SUM的初始值
str r0, [sp, #8] @sum将始终占用SP+8的位置
str r0, [sp, #4] @a将始终占用SP+4的位置
b .LBB1_1 @跳到循环开始位置
.LBB1_1: @循环开始位置
ldr r0, [sp, #4] @取出a的值给r0
cmp r0, #99 @99比较
bgt .LBB1_4 @大于99,跳出循环
b .LBB1_2 @小于,继续循环
.LBB1_2: @符合循环条件
ldr r0, [sp, #8] @取出sum的值给r0,sp+8用于写SUM的值
str r0, [sp] @先保存SUM的值,SP的位置用于读SUM
ldr r0, [sp, #4] @r0用于传参,取出A的值给r0作为fp的参数
bl fp(int) @跳转到fp执行
mov r1, r0 @fp的返回值为r0,保存到r1
ldr r0, [sp] @取出SUM的值
add r0, r0, r1 @计算新SUM的值
str r0, [sp, #8] @保存到SP+8的位置
b .LBB1_3 @无条件跳转
.LBB1_3: @执行a++的操作
ldr r0, [sp, #4] @SP+4中记录是a的值,赋给r0
add r0, r0, #1 @r0增加1
str r0, [sp, #4] @把新的a值放回SP+4里去
b .LBB1_1 @跳转到比较 a < 100
.LBB1_4: @循环结束
ldr r0, [sp, #8] @最后SUM的结果给R0,返回值的工作一直是交给R0
mov sp, r11 @重置SP的位置,改变SP就是改变了
pop {r11, lr} @弹出r11lr,lr是专用标签,弹出就自动复制给lr寄存器
bx lr @子程序返回,跳转到lr处等同于 MOV PC, LR
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册