Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
鸿蒙内核源码分析
注释鸿蒙内核源码
提交
821e846b
注释鸿蒙内核源码
项目概览
鸿蒙内核源码分析
/
注释鸿蒙内核源码
通知
270
Star
29
Fork
11
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
106
Wiki
分析
仓库
DevOps
项目成员
Pages
注释鸿蒙内核源码
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
106
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
821e846b
编写于
3月 24, 2021
作者:
鸿蒙内核源码分析
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
异常分发,缺页中断 汇编部分代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://my.oschina.net/weharmony
上级
ad4e941c
变更
4
展开全部
隐藏空白更改
内联
并排
Showing
4 changed file
with
140 addition
and
123 deletion
+140
-123
README.md
README.md
+54
-55
arch/arm/arm/src/los_exc.c
arch/arm/arm/src/los_exc.c
+12
-3
arch/arm/arm/src/los_hw_exc.S
arch/arm/arm/src/los_hw_exc.S
+73
-64
zzz/git/push.sh
zzz/git/push.sh
+1
-1
未找到文件。
README.md
浏览文件 @
821e846b
此差异已折叠。
点击以展开。
arch/arm/arm/src/los_exc.c
浏览文件 @
821e846b
...
...
@@ -117,7 +117,7 @@ STATIC UINTPTR g_minAddr;
STATIC
UINTPTR
g_maxAddr
;
STATIC
UINT32
g_currHandleExcCpuID
=
INVALID_CPUID
;
VOID
OsExcHook
(
UINT32
excType
,
ExcContext
*
excBufAddr
,
UINT32
far
,
UINT32
fsr
);
UINT32
g_curNestCount
[
LOSCFG_KERNEL_CORE_NUM
]
=
{
0
};
//
UINT32
g_curNestCount
[
LOSCFG_KERNEL_CORE_NUM
]
=
{
0
};
//
记录当前嵌套异常的数量
BOOL
g_excFromUserMode
[
LOSCFG_KERNEL_CORE_NUM
];
//记录CPU core 异常来自用户态还是内核态 TRUE为用户态,默认为内核态
STATIC
EXC_PROC_FUNC
g_excHook
=
(
EXC_PROC_FUNC
)
OsExcHook
;
//全局异常处理钩子
#if (LOSCFG_KERNEL_SMP == YES)
...
...
@@ -239,7 +239,11 @@ STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR)
ret
=
OsDecodeFS
(
bitsFS
);
return
ret
;
}
//共享页缺失异常
/*
* 共享页缺失异常
* 异常状态寄存器(Fault Status Register -FAR)
* 异常地址寄存器(Fault Address Register -FSR)
*/
UINT32
OsArmSharedPageFault
(
UINT32
excType
,
ExcContext
*
frame
,
UINT32
far
,
UINT32
fsr
)
{
PRINT_INFO
(
"page fault entry!!!
\n
"
);
...
...
@@ -1040,7 +1044,12 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr)
* Description : EXC handler entry
* Input : excType --- exc type
* excBufAddr --- address of EXC buf
*/
//异常处理的执行入口,由汇编语言层调用 见于 los_hw_exc.s 文件
*/
/*异常处理的执行入口,由汇编语言层调用 见于 los_hw_exc.s 文件
* 参数excBufAddr为异常发生时保存下来寄存器的值.
* 异常状态寄存器(Fault Status Register -FAR)
* 异常地址寄存器(Fault Address Register -FSR)
*/
LITE_OS_SEC_TEXT_INIT
VOID
OsExcHandleEntry
(
UINT32
excType
,
ExcContext
*
excBufAddr
,
UINT32
far
,
UINT32
fsr
)
{
/* Task scheduling is not allowed during exception handling */
//异常处理期间不允许任务调度
...
...
arch/arm/arm/src/los_hw_exc.S
浏览文件 @
821e846b
...
...
@@ -170,11 +170,18 @@ _osExceptUndefInstrHdl:@出现未定义的指令处理
B
_osExceptDispatch
@
Branch
to
global
exception
handler
.
#
endif
/*
STMIB
(地址先增而后完成操作)、
STMFA
(满递增堆栈);
STMIA
(完成操作而后地址递增)、
STMEA
(空递增堆栈);
STMDB
(地址先减而后完成操作)、
STMFD
(满递减堆栈);
STMDA
(完成操作而后地址递减)、
STMED
(空递减堆栈)。
*/
@
Description
:
Software
interrupt
exception
handler
_osExceptSwiHdl
:
@软中断异常处理
@保存任务上下文(
TaskContext
)
开始
...
一定要对照
TaskContext
来理解
SUB
SP
,
SP
,
#(
4
*
16
)
@
先申请
16
个栈空间用于处理本次软中断
STMIA
SP
,
{
R0
-
R12
}
@
保存
R0
-
R12
寄存器值
STMIA
SP
,
{
R0
-
R12
}
@
TaskContext
.
R
[
GEN_REGS_NUM
]
STMIA
从左到右执行
,
先放
R0
..
R12
MRS
R3
,
SPSR
@
读取本模式下的
SPSR
值
MOV
R4
,
LR
@
保存回跳寄存器
LR
...
...
@@ -185,18 +192,18 @@ _osExceptSwiHdl: @软中断异常处理
@
we
enter
from
user
mode
,
we
need
get
the
values
of
USER
mode
r13
(
sp
)
and
r14
(
lr
)
.
@
stmia
with
^
will
return
the
user
mode
registers
(
provided
that
r15
is
not
in
the
register
list
)
.
MOV
R0
,
SP
@
获取
SP
值
,
R0
将作为
OsArmA32SyscallHandle
的参数
STMFD
SP
!,
{
R3
}
@
Save
the
CPSR
入栈保存
CPSR
值
STMFD
SP
!,
{
R3
}
@
Save
the
CPSR
入栈保存
CPSR
值
=>
TaskContext
.
regPSR
ADD
R3
,
SP
,
#(
4
*
17
)
@
Offset
to
pc
/
cpsr
storage
跳到
PC
/
CPSR
存储位置
STMFD
R3
!,
{
R4
}
@
Save
the
CPSR
and
r15
(
pc
)
保存
LR
寄存器
STMFD
R3
,
{
R13
,
R14
}^
@
Save
user
mode
r13
(
sp
)
and
r14
(
lr
)
保存用户模式下的
SP
和
LR
寄存器
SUB
SP
,
SP
,
#
4
STMFD
R3
!,
{
R4
}
@
Save
the
CPSR
and
r15
(
pc
)
保存
LR
寄存器
=>
TaskContext
.
PC
STMFD
R3
,
{
R13
,
R14
}^
@
Save
user
mode
r13
(
sp
)
and
r14
(
lr
)
从右向左
保存
=>
TaskContext
.
LR
和
SP
SUB
SP
,
SP
,
#
4
@
=>
TaskContext
.
resved
PUSH_FPU_REGS
R1
@
保存中断模式
(
用户模式模式
)
@保存任务上下文(
TaskContext
)
结束
MOV
FP
,
#
0
@
Init
frame
pointer
CPSIE
I
@
开中断
,
表明在系统调用期间可响应中断
BLX
OsArmA32SyscallHandle
/*
交给
C
语言处理系统调用
*/
CPSID
I
@
执行后续指令前必须先关中断
@恢复任务上下文(
TaskContext
)
开始
POP_FPU_REGS
R1
@
弹出
FP
值给
R1
ADD
SP
,
SP
,#
4
@
定位到保存旧
SPSR
值的位置
LDMFD
SP
!,
{
R3
}
@
Fetch
the
return
SPSR
弹出旧
SPSR
值
...
...
@@ -209,23 +216,24 @@ _osExceptSwiHdl: @软中断异常处理
LDMFD
SP
,
{
R13
,
R14
}^
@
Restore
user
mode
R13
/
R14
恢复用户模式的
R13
/
R14
寄存器
ADD
SP
,
SP
,
#(
2
*
4
)
@
定位到保存旧
PC
值的位置
LDMFD
SP
!,
{PC}
^
@
Return
to
user
切回用户模式运行
@恢复任务上下文(
TaskContext
)
结束
OsKernelSVCHandler
:
ADD
R0
,
SP
,
#(
4
*
16
)
@
R0
=
sp
+
64
MOV
R5
,
R0
STMFD
R0
!,
{
R4
}
@
Store
PC
STMFD
R0
!,
{
R4
}
STMFD
R0
!,
{
R5
}
OsKernelSVCHandler
:
@主要目的是保存
ExcContext
中除(
R0
~
R12
)的其他寄存器
ADD
R0
,
SP
,
#(
4
*
16
)
@
跳转到保存
PC
,
LR
,
SP
的位置
,
此时
R0
位置刚好是
SP
的位置
MOV
R5
,
R0
@
由
R5
记录
SP
位置
,
因为
R0
要暂时充当
SP
寄存器来使用
STMFD
R0
!,
{
R4
}
@
Store
PC
=>
ExcContext
.
PC
STMFD
R0
!,
{
R4
}
@
相当于保存了
=>
ExcContext
.
LR
STMFD
R0
!,
{
R5
}
@
相当于保存了
=>
ExcContext
.
SP
STMFD
SP
!,
{
R3
}
@
Push
task
`
s
CPSR
(
i
.
e
.
exception
SPSR
)
.
SUB
SP
,
SP
,
#(
4
*
2
)
@
user
sp
and
lr
STMFD
SP
!,
{
R3
}
@
Push
task
`
s
CPSR
(
i
.
e
.
exception
SPSR
)
.
=>
ExcContext
.
regPSR
SUB
SP
,
SP
,
#(
4
*
2
)
@
user
sp
and
lr
=>
=>
ExcContext
.
USP
,
ULR
MOV
R0
,
#
OS_EXCEPT_SWI
@
Set
exception
ID
to
OS_EXCEPT_SWI
.
@
设置异常
ID
为软中断
B
_osExceptionSwi
@
Branch
to
global
exception
handler
.
@
跳到
软中断
处理
@
跳到
全局异常
处理
@
Description
:
Prefectch
abort
exception
handler
_osExceptPrefetchAbortHdl
:
_osExceptPrefetchAbortHdl
:
@预取异常处理
#ifdef LOSCFG_GDB
#if __LINUX_ARM_ARCH__ >= 7
GDB_HANDLE
OsPrefetchAbortExcHandleEntry
...
...
@@ -240,7 +248,7 @@ _osExceptPrefetchAbortHdl:
AND
R4
,
R1
,
#
CPSR_MASK_MODE
@
Interrupted
mode
CMP
R4
,
#
CPSR_USER_MODE
@
User
mode
BEQ
_osExcPageFault
@
Branch
if
user
mode
BEQ
_osExcPageFault
@
Branch
if
user
mode
_osKernelExceptPrefetchAbortHdl
:
MOV
LR
,
R5
...
...
@@ -282,10 +290,11 @@ _osExceptFiqHdl: @快中断异常处理
@
设置参数异常类型
,
将作为参数传给
_osExceptDispatch
B
_osExceptDispatch
@
Branch
to
global
exception
handler
.
_osExcPageFault
:
@缺页
异常
处理函数
_osExcPageFault
:
@缺页
中断
处理函数
SUB
R3
,
SP
,
#(
8
*
4
)
@
Save
the
start
address
of
working
registers
.
MSR
CPSR_c
,
#(
CPSR_INT_DISABLE
|
CPSR_SVC_MODE
)
@
Switch
to
SVC
mode
,
and
disable
all
interrupts
MOV
R2
,
SP
@按
ExcContext
格式开始保存现场
因为
OsArmSharedPageFault
第二个参数就是
ExcContext
STMFD
SP
!,
{
R5
}
@
Push
original
PC
STMFD
SP
!,
{
LR
}
@
Push
original
svc
LR
STMFD
SP
!,
{
R2
}
@
Push
original
svc
SP
...
...
@@ -295,31 +304,31 @@ _osExcPageFault: @缺页异常处理函数
STMFD
SP
!,
{
R1
}
SUB
SP
,
SP
,
#
8
STMIA
SP
,
{
R13
,
R14
}^
@
Save
user
mode
r13
(
sp
)
and
r14
(
lr
)
MOV
R4
,
SP
@按
ExcContext
格式完成保存现场
MOV
R4
,
SP
@
R4
指向
SP
即
ExcContext
开始位置
BIC
SP
,
SP
,
#
7
PUSH_FPU_REGS
R1
CMP
R0
,
#
OS_EXCEPT_DATA_ABORT
CMP
R0
,
#
OS_EXCEPT_DATA_ABORT
@
从正确的地址中取数据发生异常
BNE
1
f
MRC
P15
,
0
,
R2
,
C6
,
C0
,
0
MRC
P15
,
0
,
R3
,
C5
,
C0
,
0
MRC
P15
,
0
,
R2
,
C6
,
C0
,
0
@
参数
3
UINT32
far
异常地址寄存器
(
Fault
Address
Register
-
FSR
)
MRC
P15
,
0
,
R3
,
C5
,
C0
,
0
@
参数
4
UINT32
fsr
异常状态寄存器
(
Fault
Status
Register
-
FSR
)
B
2
f
1
:
MRC
P15
,
0
,
R2
,
C6
,
C0
,
2
MRC
P15
,
0
,
R3
,
C5
,
C0
,
1
2
:
MOV
R1
,
R4
2
:
MOV
R1
,
R4
@
参数
R1
即
ExcContext
开始位置
MOV
R5
,
R0
MOV
R8
,
R2
MOV
R9
,
R3
CPSIE
I
BLX
OsArmSharedPageFault
CPSID
I
CPSIE
I
@
禁止中断
BLX
OsArmSharedPageFault
@
缺页中断处理参数
(
UINT32
excType
,
ExcContext
*
frame
,
UINT32
far
,
UINT32
fsr
)
CPSID
I
@
恢复中断
POP_FPU_REGS
R1
MOV
SP
,
R4
CMP
R0
,
#
0
BEQ
_OsExcReturn
BEQ
_OsExcReturn
@
异常返回
MOV
R0
,
R5
@
exc
type
B
_osExceptionSwi
@
跳到软中断执行
,
系统调用就是通过软中断实现
...
...
@@ -335,17 +344,17 @@ _osExceptDispatch: @处理异常分发
MSR
CPSR_c
,
#(
CPSR_INT_DISABLE
|
CPSR_SVC_MODE
)
@
Switch
to
SVC
mode
,
and
disable
all
interrupts
@
切换到
SVC
模式
,
屏蔽掉所有中断
MOV
R5
,
SP
@
R5
=
SP
,
保存
SP
位置
EXC_SP_SET
__exc_stack_top
,
OS_EXC_STACK_SIZE
,
R6
,
R7
@
切换到当前
CPU
的
SVC
模式栈处理
STMFD
SP
!,
{
R1
}
@
Push
Exception
PC
保存上一个工作模式的
PC
STMFD
SP
!,
{
LR
}
@
Push
SVC
LR
保存上一个工作模式的
LR
STMFD
SP
!,
{
R5
}
@
Push
SVC
SP
保存上一个工作模式的
SP
STMFD
SP
!,
{
R8
-
R12
}
@
Push
original
R12
-
R8
,
保存上一个工作模式的
R8
-
R12
EXC_SP_SET
__exc_stack_top
,
OS_EXC_STACK_SIZE
,
R6
,
R7
@
切换到当前
CPU
的
SVC
模式栈处理
,
R6
,
R7
用于记录
CPUid
和偏移量
@开始
保存异常上下文
(
ExcContext
)
值
,
顺序是
USP
,
ULR
,
SPSR
,
R0
~
R15
STMFD
SP
!,
{
R1
}
@
Push
Exception
PC
保存上一个工作模式的
PC
=>
ExcContext
.
PC
STMFD
SP
!,
{
LR
}
@
Push
SVC
LR
保存上一个工作模式的
LR
=>
ExcContext
.
LR
STMFD
SP
!,
{
R5
}
@
Push
SVC
SP
保存上一个工作模式的
SP
=>
ExcContext
.
SP
STMFD
SP
!,
{
R8
-
R12
}
@
Push
original
R12
-
R8
,
保存上一个工作模式的
R8
-
R12
=>
ExcContext
.
R8
-
R12
LDMFD
R3
!,
{
R4
-
R11
}
@
Move
original
R7
-
R0
from
exception
stack
to
original
stack
.
@
将保存在上一个工作模式的
R0
~
R7
取出
STMFD
SP
!,
{
R4
-
R11
}
@
将上一个工作模式的
R0
~
R7
保存到新的栈中
STMFD
SP
!,
{
R2
}
@
Push
task
`
s
CPSR
(
i
.
e
.
exception
SPSR
)
.
@
任务的
CPSR
入栈
STMFD
SP
!,
{
R4
-
R11
}
@
将上一个工作模式的
R0
~
R7
保存到新的栈中
=>
ExcContext
.
R0
-
R7
STMFD
SP
!,
{
R2
}
@
Push
task
`
s
CPSR
(
i
.
e
.
exception
SPSR
)
.
=>
ExcContext
.
regCPSR
@除了
ExcContext
.
USP
,
ULR
两个值,保存异常上下文(
ExcContext
)其他值完成.
CMP
R0
,
#
OS_EXCEPT_DATA_ABORT
@
是数据异常吗
?
BNE
1
f
@
不是跳到
锚点
1
处
MRC
P15
,
0
,
R8
,
C6
,
C0
,
0
@
R8
=
C6
(
内存失效的地址
)
0
(
访问数据失效
)
...
...
@@ -358,58 +367,58 @@ _osExceptDispatch: @处理异常分发
B
3
f
@
直接跳到
锚点
3
:
处执行
2
:
MOV
R8
,
#
0
@
R8
=
0
MOV
R9
,
#
0
@
R9
=
0
@可看出异常过后,
R8
,
R9
的值发生变化,获取协处理对应的数据.
3
:
AND
R2
,
R2
,
#
CPSR_MASK_MODE
@
获取当前工作模式
CMP
R2
,
#
CPSR_USER_MODE
@
User
mode
是否为用户模式
BNE
4
f
@
不是用户模式
,
跳到
锚点
4
:
处运行
STMFD
SP
,
{
R13
,
R14
}^
@
save
user
mode
sp
and
lr
保存用户模式的
SP
和
LR
4
:
SUB
SP
,
SP
,
#(
4
*
2
)
@
sp
=
sp
-(
4
*
2
)
指向真正的栈顶
_osExceptionSwi
:
@
软中断的处理,系统调用就是由软中断实现的
4
:
@保存
=>
ExcContext
.
USP
,
ULR
SUB
SP
,
SP
,
#(
4
*
2
)
@
非用户模式下不需要保存
USP
,
ULR
,
所以跳过
2
个空间
@填充好
ExcContext
.
USP
,
ULR
两个值,
R8
,
R9
获得异常的信息
,
将接着往下执行
_osExceptionSwi
:
@
异常软处理
MOV
R1
,
SP
@
The
second
argument
to
the
exception
@
异常的第二个参数
,
第一个参数是
R0
MRC
P15
,
0
,
R4
,
C0
,
C0
,
5
@
R4
获取当前
cpu
id
AND
R4
,
R4
,
#
MPIDR_CPUID_MASK
@
Get
Current
cpu
id
LSL
R2
,
R4
,
#
2
@
(
Logic
Shift
Left
)
逻辑左移指令
R2
=
R4
<<
2
@
note_why
没看明白这句话的含义
LDR
R3
,
=
g_curNestCount
@
if
(
g_curNestCount
>
0
)
dump
to
_osExceptionGetSP
LDR
R3
,
=
g_curNestCount
@
if
(
g_curNestCount
>
0
)
dump
to
_osExceptionGetSP
嵌套异常
@将
g_curNestCount
的地址存入
R3
ADD
R3
,
R3
,
R2
@
R3
=
R3
+
R2
LDR
R4
,
[
R3
]
@
R4
=
*
R3
ADD
R3
,
R3
,
R2
@
R3
=
R3
+
R2
,
LDR
R4
,
[
R3
]
@
R4
=
*
R3
CMP
R4
,
#
0
@
R4
和
0
对比
BNE
_osExceptionGetSP
@
不相等则跳转
BNE
_osExceptionGetSP
@
(
g_curNestCount
>
0
)
说明有嵌套异常
,
必须先处理异常
@判断异常发生在任务堆栈或系统堆栈中
LDR
R3
,
=
g_intCount
@
Judge
the
exception
is
occur
in
task
stack
or
system
stack
ADD
R3
,
R3
,
R2
LDR
R4
,
[
R3
]
LDR
R4
,
[
R3
]
@
获取
g_intCount
[
ArchCurrCpuid
()]
的值
@软中断的优先级要低于硬中断,这里判断是否有硬中断发生,有则需先处理硬中断
CMP
R4
,
#
0
@
if
(
g_intCount
[
ArchCurrCpuid
()]
>
0
)
当前有中断要处理
BNE
_osExceptionGetSP
@
can
not
switch
svc
stack
无法切换到
svc
堆栈
@切换到
统一异常堆栈(
SVC
栈)
BNE
_osExceptionGetSP
@
can
not
switch
svc
stack
有中断要处理
,
必须先处理异常
@切换到
SVC
栈中处理未定义的异常
EXC_SP_SET
__svc_stack_top
,
OS_EXC_SVC_STACK_SIZE
,
R6
,
R7
@
Switch
to
unified
exception
stack
.
ADD
R4
,
R4
,
#
1
STR
R4
,
[
R3
]
_osExceptionGetSP
:
MOV
R2
,
R8
@
far
从
CP15
的
c6
获取
MOV
R3
,
R9
@
fsr
从
CP15
的
c5
获取
LDR
R5
,
=
OsExcHandleEntry
@
OsExcHandleEntry
(
UINT32
excType
,
ExcContext
*
excBufAddr
)
_osExceptionGetSP
:
@处理异常
R1
=
sp
MOV
R2
,
R8
@
far
从
CP15
的
c6
获取
异常地址寄存器
(
Fault
Address
Register
-
FSR
)
MOV
R3
,
R9
@
fsr
从
CP15
的
c5
获取
异常状态寄存器
(
Fault
Status
Register
-
FSR
)
LDR
R5
,
=
OsExcHandleEntry
@
OsExcHandleEntry
(
UINT32
excType
,
ExcContext
*
excBufAddr
,
UINT32
far
,
UINT32
fsr
)
BX
R5
@
LDR
为加载指令把
OsExcHandleEntry
的地址放入
R5
,
BX
为带分支的跳转指令
,
去执行
OsExcHandleEntry
_OsExcReturn
:
_OsExcReturn
:
@异常返回
LDR
R0
,
[
SP
,
#(
2
*
4
)]
AND
R0
,
R0
,
#
CPSR_MASK_MODE
CMP
R0
,
#
CPSR_USER_MODE
@
User
mode
BNE
_OsExcReturnToKernel
@
非用户模式跳转执行
LDMFD
SP
,
{
R13
,
R14
}^
@
load
user
mode
sp
and
lr
_OsExcReturnToKernel
:
ADD
SP
,
SP
,
#(
2
*
4
)
LDMFD
SP
!,
{
R1
}
MSR
SPSR_cxsf
,
R1
@
Set
the
return
mode
SPSR
LDMFD
SP
!,
{
R0
-
R12
}
ADD
SP
,
SP
,
#
4
LDMFD
SP
!,
{
LR
,
PC
}^
LDMFD
SP
,
{
R13
,
R14
}^
@
load
user
mode
sp
and
lr
@恢复
sp
和
lr
的值
<
=
ExcContext
.
USP
,
ULR
回到用户栈继续运行
_OsExcReturnToKernel
:
@内核模式的异常返回
ADD
SP
,
SP
,
#(
2
*
4
)
@
先跳开
ExcContext
.
USP
和
ULR
LDMFD
SP
!,
{
R1
}
@
取出
R1
=
ExcContext
.
SPSR
MSR
SPSR_cxsf
,
R1
@
Set
the
return
mode
SPSR
<
=
ExcContext
.
regCPSR
LDMFD
SP
!,
{
R0
-
R12
}
@
依次恢复
R0
~
R12
<
=
ExcContext
.
R0
-
R12
ADD
SP
,
SP
,
#
4
@
跳过
ExcContext
.
SP
LDMFD
SP
!,
{
LR
,
PC
}^
@
恢复
LR
和
PC
的值
<
=
ExcContext
.
LR
,
PC
.
end
zzz/git/push.sh
浏览文件 @
821e846b
git add
-A
git commit
-m
'
鸿蒙内核源码分析(中断管理篇) | 硬中断的实现类似观察者模式 | 百篇博客分析鸿蒙源码 | v44.01
git commit
-m
'
异常分发,缺页中断 汇编部分代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://my.oschina.net/weharmony
'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录