keil中混合编程的UNDEFINED SYMBOL问题
刚学习ucosii,准备把它移植的51上参照书本上的写了与CPU相关的几个函数编译后遇到一个很是奇怪的问题。在OS_CPU_A.asm文件中?PR?OSIntCtxSw?OS_CPU_A SEGMENT CODE PUBLIC OSIntCtxSw RSEG ?PR?OSCtxSw?OS_CPU_AOSCtxSw:
PUSHALL
OSIntCtxSw_in:
;获得堆栈长度和起址
MOVA,SP
CLRC
SUBB A,#OSStkStart
MOVR5,A ;获得堆栈长度
;OSTCBCur ===> DPTR获得当前TCB指针,详见C51.PDF第178页
MOVR0,#LOW (OSTCBCur) ;获得OSTCBCur指针低地址,指针占3字节。+0类型+1高8位数据+2低8位数据
INCR0
MOVDPH,@R0 ;全局变量OSTCBCur在IDATA中
INCR0
MOVDPL,@R0
;OSTCBCur->OSTCBStkPtr ===> DPTR获得用户堆栈指针
INCDPTR ;指针占3字节。+0类型+1高8位数据+2低8位数据
MOVX A,@DPTR ;.OSTCBStkPtr是void指针
MOVR0,A
INCDPTR
MOVX A,@DPTR
MOVR1,A
MOVDPH,R0
MOVDPL,R1
;保存堆栈长度
MOVA,R5
MOVX @DPTR,A
MOVR0,#OSStkStart;获得堆栈起址
save_stack:
INCDPTR
INCR0
MOVA,@R0
MOVX @DPTR,A
DJNZ R5,save_stack
;保存仿真堆栈指针?C_XBP
INCDPTR
MOVA,?C_XBP ;?C_XBP 仿真堆栈指针高8位
MOVX @DPTR,A
INCDPTR
MOVA,?C_XBP+1;?C_XBP 仿真堆栈指针低8位
MOVX @DPTR,A
;调用用户程序
LCALL _?OSTaskSwHook
;OSTCBCur = OSTCBHighRdy
MOVR0,#OSTCBCur
MOVR1,#OSTCBHighRdy
MOVA,@R1
MOV@R0,A
INCR0
INCR1
MOVA,@R1
MOV@R0,A
INCR0
INCR1
MOVA,@R1
MOV@R0,A
;OSPrioCur = OSPrioHighRdy使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。
MOVR0,#OSPrioCur
MOVR1,#OSPrioHighRdy
MOVA,@R1
MOV@R0,A
LJMP OSCtxSw_in可是已编译就出现问题了..\..\uCOS-II\Ports\os_cpu_a.asm(34): error A45: UNDEFINED SYMBOL (PASS-2)
这个错误我的理解是OSIntCtxSw 模块没有定义,可是我程序中明明是有定义的啊?
在keil官网上下了个c和asm混合编程的例子其中汇编部分为NAME A_FUNC
?PR?a_func?A_FUNC SEGMENT CODE
EXTRN CODE (c_func)
PUBLIC a_func
RSEG?PR?a_func?A_FUNC
a_func:
USING 0
LCALL c_func
RET
END
编译没有问题,一开始我就让为在段命名方面可能有问题于是我把上面的程序改了下NAME A_FUNC
?PR?OSIntCtxSw?A_FUNC SEGMENT CODE
EXTRN CODE (c_func)
PUBLIC OSIntCtxSw
RSEG?PR?OSIntCtxSw?A_FUNC
a_func:
USING 0
LCALL c_func
RET
END
编译后果然同样的问题出现了
a_func.a51(5): error A45: UNDEFINED SYMBOL (PASS-2)
不知道这个错误到底是为什么,希望大侠帮忙,谢谢
终于找出答案了,原来使用RSEG命令后紧接着一行即: RSEG ?PR?OSIntCtxSw?OS_CPU_A
OSIntCtxSw:
USING 0
LCALL OSTaskSwHook
MOVA, SP /*去除多入栈的4字节 */
CLRC
SUBB A, #4
MOVSP, A
MOVA, SP /*计算公栈长度 */
CLRC
SUBB A, #OSStkStart
MOVR7, A
MOVR0, #LOW(OSTCBCur) /* 获取当前任务控制块指针 */
INCR0
MOVDPH, @R0
INC R0
MOVDPL, @R0
INCDPTR /* 获取当前任务堆栈指针 */
MOVX A, @DPTR
MOVR0, A
INCDPTR
MOVX A, @DPTR
MOVR1, A
MOVDPH, R0
MOVDPL, R1
MOV A, R7 /* 保存公栈长度 */
MOVX @DPTR, A
MOVR0, #OSStkStart /*保存公栈到私栈 */
Save_Stack_C:
INCDPTR
INCR0
MOVA, @R0
MOVX @DPTR, A
DJNZ R7, Save_Stack_C
要使用一个标号并且这个标号和这个函数的名称是一样的 顶一下!
页:
[1]