在Borland C++6 中的c语言项目中加入OS_CPU_A.ASM文件,编译后报错 ( 积分: 100 )

  • 主题发起人 主题发起人 LEYT8
  • 开始时间 开始时间
L

LEYT8

Unregistered / Unconfirmed
GUEST, unregistred user!
在实模式、大模式下编译uC/OS_ii
在Borland C++6 中的c语言项目中加入OS_CPU_A.ASM文件,编译后报错如下:
[Linker Fatal Error] Fatal: Unsupported 16-bit segment(s) in module H:/SOFTWARE/uCOS/Ix86L/BC45/OS_CPU_A.ASM
估计是由于OS_CPU_A.ASM文件中的命令为16位的,无法和Borland C++6编译的32位的程序兼容造成的;但是如何才能解决这个问题呢???
Borland C/C++ V4.51(Borland Turbo C++ 4.5)是否为16位的,在哪里能得到???
下面是OS_CPU_A.ASM文件,如何才能编译通过?请诸位大虾指教!!
;********************************************************************************************************
;
PUBLIC and EXTERNAL REFERENCES
;********************************************************************************************************
PUBLIC _OSTickISR
PUBLIC _OSStartHighRdy
PUBLIC _OSCtxSw
PUBLIC _OSIntCtxSw
EXTRN _OSIntExit:FAR
EXTRN _OSTimeTick:FAR
EXTRN _OSTaskSwHook:FAR
EXTRN _OSIntNesting:BYTE
EXTRN _OSTickDOSCtr:BYTE
EXTRN _OSPrioHighRdy:BYTE
EXTRN _OSPrioCur:BYTE
EXTRN _OSRunning:BYTE
EXTRN _OSTCBCur:DWORD
EXTRN _OSTCBHighRdy:DWORD
.MODEL LARGE
.CODE
.186
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
START MULTITASKING
;
void OSStartHighRdy(void)
;
;
The stack frame is assumed to look as follows:
;
;
OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW
;
OFFSET of task code address
;
SEGMENT of task code address
;
OFFSET of 'pdata'
;
SEGMENT of 'pdata' (High memory)
;
;
Note : OSStartHighRdy() MUST:
;
a) Call OSTaskSwHook() then
,
;
b) Set OSRunning to TRUE,
;
c) Switch to the highest priority task.
;*********************************************************************************************************
_OSStartHighRdy PROC FAR
MOV AX, SEG _OSTCBHighRdy ;
Reload DS
MOV DS, AX ;
;
CALL FAR PTR _OSTaskSwHook ;
Call user defined task switch hook
;
MOV AL, 1 ;
OSRunning = TRUE;
MOV BYTE PTR DS:_OSRunning, AL ;
(Indicates that multitasking has started)
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ;
SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX+0] ;
;
POP DS ;
Load task's context
POP ES ;
POPA ;
;
IRET ;
Run task
_OSStartHighRdy ENDP
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
PERFORM A CONTEXT SWITCH (From task level)
;
void OSCtxSw(void)
;
;
Note(s): 1) Upon entry,
;
OSTCBCur points to the OS_TCB of the task to suspend
;
OSTCBHighRdy points to the OS_TCB of the task to resume
;
;
2) The stack frame of the task to suspend looks as follows:
;
;
SP -> OFFSET of task to suspend (Low memory)
;
SEGMENT of task to suspend
;
PSW of task to suspend (High memory)
;
;
3) The stack frame of the task to resume looks as follows:
;
;
OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW (High memory)
;*********************************************************************************************************
_OSCtxSw PROC FAR
;
PUSHA ;
Save current task's context
PUSH ES ;
PUSH DS ;
;
MOV AX, SEG _OSTCBCur ;
Reload DS in case it was altered
MOV DS, AX ;
;
LES BX, DWORD PTR DS:_OSTCBCur ;
OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
;
CALL FAR PTR _OSTaskSwHook ;
Call user defined task switch hook
;
MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ;
OSTCBCur = OSTCBHighRdy
MOV DX, WORD PTR DS:_OSTCBHighRdy ;
MOV WORD PTR DS:_OSTCBCur+2, AX ;
MOV WORD PTR DS:_OSTCBCur, DX ;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy ;
OSPrioCur = OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL ;
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ;
SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX] ;
;
POP DS ;
Load new task's context
POP ES ;
POPA ;
;
IRET ;
Return to new task
;
_OSCtxSw ENDP
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
PERFORM A CONTEXT SWITCH (From an ISR)
;
void OSIntCtxSw(void)
;
;
Note(s): 1) Upon entry,
;
OSTCBCur points to the OS_TCB of the task to suspend
;
OSTCBHighRdy points to the OS_TCB of the task to resume
;
;
2) The stack frame of the task to suspend looks as follows:
;
;
OSTCBCur->OSTCBStkPtr ------> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW (High memory)
;
;
;
3) The stack frame of the task to resume looks as follows:
;
;
OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW (High memory)
;*********************************************************************************************************
_OSIntCtxSw PROC FAR
;
CALL FAR PTR _OSTaskSwHook ;
Call user defined task switch hook
;
MOV AX, SEG _OSTCBCur ;
Reload DS in case it was altered
MOV DS, AX ;
;
MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ;
OSTCBCur = OSTCBHighRdy
MOV DX, WORD PTR DS:_OSTCBHighRdy ;
MOV WORD PTR DS:_OSTCBCur+2, AX ;
MOV WORD PTR DS:_OSTCBCur, DX ;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy ;
OSPrioCur = OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ;
SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX] ;
;
POP DS ;
Load new task's context
POP ES ;
POPA ;
;
IRET ;
Return to new task
;
_OSIntCtxSw ENDP
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
HANDLE TICK ISR
;
;
Description: This function is called 199.99 times per second or, 11 times faster than the normaldo
S
;
tick rate of 18.20648 Hz. Thus every 11th time, the normaldo
S tick handler is called.
;
This is called chaining. 10 times out of 11, however, the interrupt controller on the PC
;
must be cleared to allow for the next interrupt.
;
;
Arguments : none
;
;
Returns : none
;
;
Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.
;
;
Save all registers on the current task's stack;
;
OSIntNesting++;
;
if (OSIntNesting == 1) {
;
OSTCBCur->OSTCBStkPtr = SS:SP
;
}
;
OSTickDOSCtr--;
;
if (OSTickDOSCtr == 0) {
;
OSTickDOSCtr = 11;
;
INT 81H;
Chain intodo
S every 54.925 mS
;
(Interrupt will be cleared bydo
S)
;
} else
{
;
Send EOI to PIC;
Clear tick interrupt by sending an End-Of-Interrupt to the 8259
;
PIC (Priority Interrupt Controller)
;
}
;
OSTimeTick();
Notify uC/OS-II that a tick has occured
;
OSIntExit();
Notify uC/OS-II about end of ISR
;
Restore all registers that were save on the current task's stack;
;
Return from Interrupt;
;*********************************************************************************************************
;
_OSTickISR PROC FAR
;
PUSHA ;
Save interrupted task's context
PUSH ES
PUSH DS
;
MOV AX, SEG(_OSIntNesting) ;
Reload DS
MOV DS, AX
INC BYTE PTR DS:_OSIntNesting ;
Notify uC/OS-II of ISR
;
CMP BYTE PTR DS:_OSIntNesting, 1 ;
if (OSIntNesting == 1)
JNE SHORT _OSTickISR1
MOV AX, SEG(_OSTCBCur) ;
Reload DS
MOV DS, AX
LES BX, DWORD PTR DS:_OSTCBCur ;
OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
;
_OSTickISR1:
MOV AX, SEG(_OSTickDOSCtr) ;
Reload DS
MOV DS, AX
DEC BYTE PTR DS:_OSTickDOSCtr
CMP BYTE PTR DS:_OSTickDOSCtr, 0
JNE SHORT _OSTickISR2 ;
Every 11 ticks (~199.99 Hz), chain intodo
S
;
MOV BYTE PTR DS:_OSTickDOSCtr, 11
INT 081H ;
Chain intodo
S's tick ISR
JMP SHORT _OSTickISR3
_OSTickISR2:
MOV AL, 20H ;
Move EOI code into AL.
MOV DX, 20H ;
Address of 8259 PIC in DX.
OUT DX, AL ;
Send EOI to PIC if not processingdo
S timer.
;
_OSTickISR3:
CALL FAR PTR _OSTimeTick ;
Process system tick
;
CALL FAR PTR _OSIntExit ;
Notify uC/OS-II of end of ISR
;
POP DS ;
Restore interrupted task's context
POP ES
POPA
;
IRET ;
Return to interrupted task
;
_OSTickISR ENDP
;
END
 
在实模式、大模式下编译uC/OS_ii
在Borland C++6 中的c语言项目中加入OS_CPU_A.ASM文件,编译后报错如下:
[Linker Fatal Error] Fatal: Unsupported 16-bit segment(s) in module H:/SOFTWARE/uCOS/Ix86L/BC45/OS_CPU_A.ASM
估计是由于OS_CPU_A.ASM文件中的命令为16位的,无法和Borland C++6编译的32位的程序兼容造成的;但是如何才能解决这个问题呢???
Borland C/C++ V4.51(Borland Turbo C++ 4.5)是否为16位的,在哪里能得到???
下面是OS_CPU_A.ASM文件,如何才能编译通过?请诸位大虾指教!!
;********************************************************************************************************
;
PUBLIC and EXTERNAL REFERENCES
;********************************************************************************************************
PUBLIC _OSTickISR
PUBLIC _OSStartHighRdy
PUBLIC _OSCtxSw
PUBLIC _OSIntCtxSw
EXTRN _OSIntExit:FAR
EXTRN _OSTimeTick:FAR
EXTRN _OSTaskSwHook:FAR
EXTRN _OSIntNesting:BYTE
EXTRN _OSTickDOSCtr:BYTE
EXTRN _OSPrioHighRdy:BYTE
EXTRN _OSPrioCur:BYTE
EXTRN _OSRunning:BYTE
EXTRN _OSTCBCur:DWORD
EXTRN _OSTCBHighRdy:DWORD
.MODEL LARGE
.CODE
.186
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
START MULTITASKING
;
void OSStartHighRdy(void)
;
;
The stack frame is assumed to look as follows:
;
;
OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW
;
OFFSET of task code address
;
SEGMENT of task code address
;
OFFSET of 'pdata'
;
SEGMENT of 'pdata' (High memory)
;
;
Note : OSStartHighRdy() MUST:
;
a) Call OSTaskSwHook() then
,
;
b) Set OSRunning to TRUE,
;
c) Switch to the highest priority task.
;*********************************************************************************************************
_OSStartHighRdy PROC FAR
MOV AX, SEG _OSTCBHighRdy ;
Reload DS
MOV DS, AX ;
;
CALL FAR PTR _OSTaskSwHook ;
Call user defined task switch hook
;
MOV AL, 1 ;
OSRunning = TRUE;
MOV BYTE PTR DS:_OSRunning, AL ;
(Indicates that multitasking has started)
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ;
SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX+0] ;
;
POP DS ;
Load task's context
POP ES ;
POPA ;
;
IRET ;
Run task
_OSStartHighRdy ENDP
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
PERFORM A CONTEXT SWITCH (From task level)
;
void OSCtxSw(void)
;
;
Note(s): 1) Upon entry,
;
OSTCBCur points to the OS_TCB of the task to suspend
;
OSTCBHighRdy points to the OS_TCB of the task to resume
;
;
2) The stack frame of the task to suspend looks as follows:
;
;
SP -> OFFSET of task to suspend (Low memory)
;
SEGMENT of task to suspend
;
PSW of task to suspend (High memory)
;
;
3) The stack frame of the task to resume looks as follows:
;
;
OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW (High memory)
;*********************************************************************************************************
_OSCtxSw PROC FAR
;
PUSHA ;
Save current task's context
PUSH ES ;
PUSH DS ;
;
MOV AX, SEG _OSTCBCur ;
Reload DS in case it was altered
MOV DS, AX ;
;
LES BX, DWORD PTR DS:_OSTCBCur ;
OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
;
CALL FAR PTR _OSTaskSwHook ;
Call user defined task switch hook
;
MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ;
OSTCBCur = OSTCBHighRdy
MOV DX, WORD PTR DS:_OSTCBHighRdy ;
MOV WORD PTR DS:_OSTCBCur+2, AX ;
MOV WORD PTR DS:_OSTCBCur, DX ;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy ;
OSPrioCur = OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL ;
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ;
SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX] ;
;
POP DS ;
Load new task's context
POP ES ;
POPA ;
;
IRET ;
Return to new task
;
_OSCtxSw ENDP
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
PERFORM A CONTEXT SWITCH (From an ISR)
;
void OSIntCtxSw(void)
;
;
Note(s): 1) Upon entry,
;
OSTCBCur points to the OS_TCB of the task to suspend
;
OSTCBHighRdy points to the OS_TCB of the task to resume
;
;
2) The stack frame of the task to suspend looks as follows:
;
;
OSTCBCur->OSTCBStkPtr ------> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW (High memory)
;
;
;
3) The stack frame of the task to resume looks as follows:
;
;
OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
;
ES
;
DI
;
SI
;
BP
;
SP
;
BX
;
DX
;
CX
;
AX
;
OFFSET of task code address
;
SEGMENT of task code address
;
Flags to load in PSW (High memory)
;*********************************************************************************************************
_OSIntCtxSw PROC FAR
;
CALL FAR PTR _OSTaskSwHook ;
Call user defined task switch hook
;
MOV AX, SEG _OSTCBCur ;
Reload DS in case it was altered
MOV DS, AX ;
;
MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ;
OSTCBCur = OSTCBHighRdy
MOV DX, WORD PTR DS:_OSTCBHighRdy ;
MOV WORD PTR DS:_OSTCBCur+2, AX ;
MOV WORD PTR DS:_OSTCBCur, DX ;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy ;
OSPrioCur = OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ;
SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX] ;
;
POP DS ;
Load new task's context
POP ES ;
POPA ;
;
IRET ;
Return to new task
;
_OSIntCtxSw ENDP
PAGE ;
/*$PAGE*/
;*********************************************************************************************************
;
HANDLE TICK ISR
;
;
Description: This function is called 199.99 times per second or, 11 times faster than the normaldo
S
;
tick rate of 18.20648 Hz. Thus every 11th time, the normaldo
S tick handler is called.
;
This is called chaining. 10 times out of 11, however, the interrupt controller on the PC
;
must be cleared to allow for the next interrupt.
;
;
Arguments : none
;
;
Returns : none
;
;
Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.
;
;
Save all registers on the current task's stack;
;
OSIntNesting++;
;
if (OSIntNesting == 1) {
;
OSTCBCur->OSTCBStkPtr = SS:SP
;
}
;
OSTickDOSCtr--;
;
if (OSTickDOSCtr == 0) {
;
OSTickDOSCtr = 11;
;
INT 81H;
Chain intodo
S every 54.925 mS
;
(Interrupt will be cleared bydo
S)
;
} else
{
;
Send EOI to PIC;
Clear tick interrupt by sending an End-Of-Interrupt to the 8259
;
PIC (Priority Interrupt Controller)
;
}
;
OSTimeTick();
Notify uC/OS-II that a tick has occured
;
OSIntExit();
Notify uC/OS-II about end of ISR
;
Restore all registers that were save on the current task's stack;
;
Return from Interrupt;
;*********************************************************************************************************
;
_OSTickISR PROC FAR
;
PUSHA ;
Save interrupted task's context
PUSH ES
PUSH DS
;
MOV AX, SEG(_OSIntNesting) ;
Reload DS
MOV DS, AX
INC BYTE PTR DS:_OSIntNesting ;
Notify uC/OS-II of ISR
;
CMP BYTE PTR DS:_OSIntNesting, 1 ;
if (OSIntNesting == 1)
JNE SHORT _OSTickISR1
MOV AX, SEG(_OSTCBCur) ;
Reload DS
MOV DS, AX
LES BX, DWORD PTR DS:_OSTCBCur ;
OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
;
_OSTickISR1:
MOV AX, SEG(_OSTickDOSCtr) ;
Reload DS
MOV DS, AX
DEC BYTE PTR DS:_OSTickDOSCtr
CMP BYTE PTR DS:_OSTickDOSCtr, 0
JNE SHORT _OSTickISR2 ;
Every 11 ticks (~199.99 Hz), chain intodo
S
;
MOV BYTE PTR DS:_OSTickDOSCtr, 11
INT 081H ;
Chain intodo
S's tick ISR
JMP SHORT _OSTickISR3
_OSTickISR2:
MOV AL, 20H ;
Move EOI code into AL.
MOV DX, 20H ;
Address of 8259 PIC in DX.
OUT DX, AL ;
Send EOI to PIC if not processingdo
S timer.
;
_OSTickISR3:
CALL FAR PTR _OSTimeTick ;
Process system tick
;
CALL FAR PTR _OSIntExit ;
Notify uC/OS-II of end of ISR
;
POP DS ;
Restore interrupted task's context
POP ES
POPA
;
IRET ;
Return to interrupted task
;
_OSTickISR ENDP
;
END
 
汇编呀?看晕了.如果不是做驱动程序,还是不用汇编的好.曾用汇编写了一个图像合并的代码,花了很多时间,结果没比pascal快多少,也就一点点吧.
 
在Win32下不支持SEG伪指令,因为win32是运行在flat模式下的.
MOV AX, SEG(_OSIntNesting) ;
Reload DS
MOV DS, AX
问题就出在上面那两行,删除掉
 
后退
顶部