5.07.2010

Log : trace tcpmp exception on CE 6.0 - assembly code

看一下 assembly code exception 的原因:
p->Entry(p,Dst,Src,*DstLength,&p->State,Volume)

對應的 assmbly code是:
41041954 E59D3044             ldr         r3, Volume, #0x44
41041958 E58D3004 str r3, [sp, #4]
4104195C E59D302C ldr r3, p, #0x2C
41041960 E2833004 add r3, r3, #4
41041964 E58D3000 str r3, [sp]
41041968 E59D3038 ldr r3, DstLength, #0x38
4104196C E5933000 ldr r3, [r3]
41041970 E59D2034 ldr r2, Src, #0x34
41041974 E59D1030 ldr r1, Dst, #0x30
41041978 E59D002C ldr r0, p, #0x2C
4104197C E59DE02C ldr lr, p, #0x2C
41041980 E59E4000 ldr r4, [lr]
41041984 E1A0E00F mov lr, pc
41041988 E1A0F004 mov pc, r4
可以看到 參數傳遞是 r0~r3,stack,stack

Entry( ) 內的 assembly code 是:
010A0000 00000000             andeq       r0, r0, r0
010A0004 00000000 andeq r0, r0, r0
010A0008 00000000 andeq r0, r0, r0
010A000C 00000000 andeq r0, r0, r0
010A0010 E59D4028 ldr r4, [sp, #0x28]
010A0014 E5947004 ldr r7, [r4, #4]
010A0018 E5948008 ldr r8, [r4, #8]
010A001C E59D002C ldr r0, [sp, #0x2C]
010A0020 E3570C01 cmp r7, #1, 24
010A0024 1A000006 bne 010A0044
010A0028 E0D920F2 ldrsh r2, [r9], #2
010A002C E0020290 mul r2, r0, r2
010A0030 E1A02442 mov r2, r2, asr #8
010A0034 E0CB20B2 strh r2, [r11], #2
010A0038 E15B000E cmp r11, lr
010A003C 1AFFFFF9 bne 010A0028
010A0040 E8BD9FF0 ldmia sp!, {r4 - r12, pc}
010A0044 E1A03428 mov r3, r8, lsr #8
010A0048 E1A03083 mov r3, r3, lsl #1
010A004C E19920F3 ldrsh r2, [r9, +r3]
010A0050 E0888007 add r8, r8, r7
010A0054 E0020290 mul r2, r0, r2
010A0058 E1A02442 mov r2, r2, asr #8
010A005C E0CB20B2 strh r2, [r11], #2
010A0060 E15B000E cmp r11, lr
010A0064 1AFFFFF6 bne 010A0044
010A0068 E8BD9FF0 ldmia sp!, {r4 - r12, pc}
看到好像argument 完全不對應,r0 甚至被破壞..
在 CompileCode( ), BuildCode( ) 完後,0x10A000 的內容:
010A0000  F0 5F 2D E9 00 B0 91 E5 03 E0 8B E0 00 90 92 E5  ._-.............
010A0010 28 40 9D E5 04 70 94 E5 08 80 94 E5 2C 00 9D E5 (@...p......,...
010A0020 01 0C 57 E3 06 00 00 1A F2 20 D9 E0 90 02 02 E0 ..W...... ......
010A0030 42 24 A0 E1 B2 20 CB E0 0E 00 5B E1 F9 FF FF 1A B$... ....[.....
010A0040 F0 9F BD E8 28 34 A0 E1 83 30 A0 E1 F3 20 99 E1 ....(4...0... ..
010A0050 07 80 88 E0 90 02 02 E0 42 24 A0 E1 B2 20 CB E0 ........B$... ..
010A0060 0E 00 5B E1 F6 FF FF 1A F0 9F BD E8 00 00 00 00 ..[.............

可以看到是不一樣的,0x10A0000 到 0x10A000F 都被清成 0x00。

之後的 code 果然跟 cache 有關,code都做完後,就要:
void CodeUnlock(void* Code,int Size)
{
DWORD Protect;
VirtualProtect(Code,Size,PAGE_EXECUTE_READ,&Protect);

if (FuncCacheSync)
FuncCacheSync(CACHE_SYNC_INSTRUCTIONS);

}
很奇怪的是,如果在這其中 break 一下(用KITL),或是完成後,用 DebugWindow 的 Memory 來 check 一下,資料就會正確。
真的是cache 的關係? 這個 ARM11 有L2 cache..

msdn 這一頁 有列出,CacheSync 是 Kernel Mode Only.

沒有留言: