|
用在RTOS中的GCC库函数itoa的悬疑
94: itoa(gRHcnt,r,10);
+000017F1: E04A LDI R20,0x0A Load immediate
+000017F2: E050 LDI R21,0x00 Load immediate
+000017F3: E16F LDI R22,0x1F Load immediate
+000017F4: E073 LDI R23,0x03 Load immediate
+000017F5: 91800311 LDS R24,0x0311 Load direct from data space
+000017F7: 91900312 LDS R25,0x0312 Load direct from data space
+000017F9: 940E1D9C CALL 0x00001D9C Call subroutine
+00001D9C: 01FB MOVW R30,R22 Copy register pair
+00001D9D: 019F MOVW R18,R30 Copy register pair
+00001D9E: 94E8 CLT Clear T in SREG
+00001D9F: 3042 CPI R20,0x02 Compare with immediate
+00001DA0: F0C4 BRLT PC+0x19 Branch if less than, signed
+00001DA1: 3245 CPI R20,0x25 Compare with immediate
+00001DA2: F4B4 BRGE PC+0x17 Branch if greater or equal, signed
+00001DA3: 304A CPI R20,0x0A Compare with immediate
+00001DA4: F429 BRNE PC+0x06 Branch if not equal
+00001DA5: FB97 BST R25,7 Bit store from register to T
+00001DA6: F41E BRTC PC+0x04 Branch if T flag cleared
+00001DA7: 9590 COM R25 One's complement
+00001DA8: 9581 NEG R24 Two's complement
+00001DA9: 4F9F SBCI R25,0xFF Subtract immediate with carry
+00001DAA: 2F64 MOV R22,R20 Copy register
+00001DAB: 2777 CLR R23 Clear Register
+00001DAC: 940E1E2D CALL 0x00001E2D Call subroutine
+00001DAE: 5D80 SUBI R24,0xD0 Subtract immediate
+00001DAF: 338A CPI R24,0x3A Compare with immediate
+00001DB0: F00C BRLT PC+0x02 Branch if less than, signed
+00001DB1: 5D89 SUBI R24,0xD9 Subtract immediate
+00001DB2: 9381 ST Z+,R24 Store indirect and postincrement
+00001DB3: 01CB MOVW R24,R22 Copy register pair
+00001DB4: 9700 SBIW R24,0x00 Subtract immediate from word
+00001DB5: F7A1 BRNE PC-0x0B Branch if not equal
+00001DB6: F416 BRTC PC+0x03 Branch if T flag cleared
+00001DB7: E25D LDI R21,0x2D Load immediate
+00001DB8: 9351 ST Z+,R21 Store indirect and postincrement
+00001DB9: 8210 STD Z+0,R1 Store indirect with displacement
---- No Source ------------------------------------------------------------------------------------
+00001DBA: 01C9 MOVW R24,R18 Copy register pair
+00001DBB: 940C1DBD JMP 0x00001DBD Jump
+00001DBD: 01DC MOVW R26,R24 Copy register pair
+00001DBE: 01FC MOVW R30,R24 Copy register pair
+00001DBF: 9001 LD R0,Z+ Load indirect and postincrement
+00001DC0: 2000 TST R0 Test for Zero or Minus
+00001DC1: F7E9 BRNE PC-0x02 Branch if not equal
+00001DC2: 9732 SBIW R30,0x02 Subtract immediate from word
+00001DC3: 17AE CP R26,R30 Compare
+00001DC4: 07BF CPC R27,R31 Compare with carry
+00001DC5: F430 BRCC PC+0x07 Branch if carry cleared
+00001DC6: 917C LD R23,X Load indirect
+00001DC7: 8160 LDD R22,Z+0 Load indirect with displacement
+00001DC8: 8370 STD Z+0,R23 Store indirect with displacement
+00001DC9: 9731 SBIW R30,0x01 Subtract immediate from word
+00001DCA: 936D ST X+,R22 Store indirect and postincrement
+00001DCB: CFF7 RJMP PC-0x0008 Relative jump
+00001DCC: 9508 RET
+00001E2D: 1BAA SUB R26,R26 Subtract without carry
+00001E2E: 1BBB SUB R27,R27 Subtract without carry
+00001E2F: E151 LDI R21,0x11 Load immediate
+00001E30: C007 RJMP PC+0x0008 Relative jump
+00001E31: 1FAA ROL R26 Rotate Left Through Carry
+00001E32: 1FBB ROL R27 Rotate Left Through Carry
+00001E33: 17A6 CP R26,R22 Compare
+00001E34: 07B7 CPC R27,R23 Compare with carry
+00001E35: F010 BRCS PC+0x03 Branch if carry set
+00001E36: 1BA6 SUB R26,R22 Subtract without carry
+00001E37: 0BB7 SBC R27,R23 Subtract with carry
+00001E38: 1F88 ROL R24 Rotate Left Through Carry
+00001E39: 1F99 ROL R25 Rotate Left Through Carry
+00001E3A: 955A DEC R21 Decrement
+00001E3B: F7A9 BRNE PC-0x0A Branch if not equal
+00001E3C: 9580 COM R24 One's complement
+00001E3D: 9590 COM R25 One's complement
+00001E3E: 01BC MOVW R22,R24 Copy register pair
+00001E3F: 01CD MOVW R24,R26 Copy register pair
+00001E40: 9508 RET
这段代码是我从avr-gcc的库文件中提取出来的,是itoa的实现。然而这个函数在抢占式的多线程环境有时得到的结果却不正常,
但只要在调用这个函数前加关中断处理就可以每次都获得正确的结果。我把这个函数的汇编实现提出来之后仔细看了好几遍,没
有发现使用除了寄存器之外其它的资源,我的任务切换如下保护:
register uint8 Os_Enter_Sum asm("r2"); // 关中断计数器使用的寄存器
#define POPALL() \
{ \
__asm__ __volatile__( \
"POP R31" "
\t" \
"POP R30" "
\t" \
"POP R29" "
\t" \
"POP R28" "
\t" \
"POP R27" "
\t" \
"POP R26" "
\t" \
"POP R25" "
\t" \
"POP R24" "
\t" \
"POP R23" "
\t" \
"POP R22" "
\t" \
"POP R21" "
\t" \
"POP R20" "
\t" \
"POP R19" "
\t" \
"POP R18" "
\t" \
"POP R17" "
\t" \
"POP R16" "
\t" \
"POP R15" "
\t" \
"POP R14" "
\t" \
"POP R13" "
\t" \
"POP R12" "
\t" \
"POP R11" "
\t" \
"POP R10" "
\t" \
"POP R9" "
\t" \
"POP R8" "
\t" \
"POP R7" "
\t" \
"POP R6" "
\t" \
"POP R5" "
\t" \
"POP R4" "
\t" \
"POP R3" "
\t" \
"POP R2" "
\t" \
"POP R0" "
\t" \
"OUT 0x3F,R0" "
\t" \
"POP R0" "
\t" \
"POP R1" "
\t" \
); \
}
#define PUSHALL() \
{ \
__asm__ __volatile__( \
"PUSH R1" "
\t" \
"PUSH R0" "
\t" \
"IN R0,0x3F" "
\t" \
"PUSH R0" "
\t" \
"CLR R1" "
\t" \
"PUSH R2" "
\t" \
"PUSH R3" "
\t" \
"PUSH R4" "
\t" \
"PUSH R5" "
\t" \
"PUSH R6" "
\t" \
"PUSH R7" "
\t" \
"PUSH R8" "
\t" \
"PUSH R9" "
\t" \
"PUSH R10" "
\t" \
"PUSH R11" "
\t" \
"PUSH R12" "
\t" \
"PUSH R13" "
\t" \
"PUSH R14" "
\t" \
"PUSH R15" "
\t" \
"PUSH R16" "
\t" \
"PUSH R17" "
\t" \
"PUSH R18" "
\t" \
"PUSH R19" "
\t" \
"PUSH R20" "
\t" \
"PUSH R21" "
\t" \
"PUSH R22" "
\t" \
"PUSH R23" "
\t" \
"PUSH R24" "
\t" \
"PUSH R25" "
\t" \
"PUSH R26" "
\t" \
"PUSH R27" "
\t" \
"PUSH R28" "
\t" \
"PUSH R29" "
\t" \
"PUSH R30" "
\t" \
"PUSH R31" "
\t" \
); \
}
但为什么有时会到不到正确的结果呢,有句话说的好“众人拾材火焰高”,希望各位网友献计献策。 |
|