我试图理解这个将堆栈指针设置为 RTOS 任务堆栈位置的程序集宏。有一些汇编命令我不知道,也找不到那么多信息。
此代码将用户堆栈指针指向 Micrium 任务 (uC/OS III RTOS) 的堆栈。但是这些任务只允许放在近内存中,这可能是因为这些汇编函数。
这就是为什么我试图找出这里到底发生了什么。以及为什么堆栈只能在内存附近。之后,我想知道是否可以重写它以支持近内存之外的任务堆栈。
此汇编代码在 XE169 芯片(C166 系列)上运行:
LOAD_USRSTK_PTR .MACRO
EXTP #PAG _OSTCBHighRdyPtr,#02h ; R4/R5 = OSTCBHighRdyPtr
MOV R4,POF _OSTCBHighRdyPtr
MOV R5,POF (_OSTCBHighRdyPtr+2)
EXTP R5,#01h ; user stack ptr = OSTCBHighRdyPtr->OSTCBStkPtr
MOV R15,[R4]
.ENDM
这是我发现每行代码的作用的程度:
LOAD_USRSTK_PTR .MACRO
名称为 LOAD_USRSTK_PTR 的宏开始
EXTP #PAG _OSTCBHighRdyPtr,#02h
开始扩展页面序列,接下来的 2 条指令是扩展页面序列的一部分
该指令中的#PAG _OSTCBHighRdyPtr 部分是什么意思,这是否获得了OSTCBHighRdyPtr 指向的地址的Page 部分。
MOV R4,POF _OSTCBHighRdyPtr
将_OSTCBHighRdyPtr写入寄存器4。POF在这条指令中是什么意思,它是否获取指针的值并将其存储在寄存器4中?
MOV R5,POF (_OSTCBHighRdyPtr+2)
将 2 个地址的值作为 OSTCBHighRdyPtr 的地址进一步写入寄存器 5。 这条指令中的 POF 是什么意思 在这种情况下是复制 ExtPtr 地址吗?因为这个地址有4个字节长,而寄存器只有2个字节?
EXTP R5,#01h ; user stack ptr = OSTCBHighRdyPtr->OSTCBStkPtr
开始扩展页面序列。Next 1 指令是扩展页面序列的一部分。R5 = 寄存器 5 这个寄存器到底做了什么
MOV R15,[R4]
将寄存器 4 的值移动到寄存器 15 中,R15 为用户堆栈指针
.ENDM
宏结束
_OSTCBHighRdyPtr 是一个指向结构的指针,这个结构的(开始)看起来像这样:
struct os_tcb {
CPU_STK *StkPtr; /* Pointer to current top of stack */
void *ExtPtr; /* Pointer to user definable data for TCB extension */
CPU_CHAR *NamePtr; /* Pointer to task name */
CPU_STK *StkLimitPtr; /* Pointer used to set stack 'watermark' limit */
....
}
CPU_STK 是 unsigned short __near 的 typedef。
此结构中项目的大小为:
StkPtr = 2 bytes (in near memory thus 2 bytes is enough)
ExtPtr = 4 bytes
NamePtr = 4 bytes
StkLimitPtr = 2 bytes (in near memory thus 2 bytes is enough)