2013-06-19 47 views
0

我写了这个调用pthread的arm汇编代码来实现多线程功能。我写了两个类似的文件,但是这个文件非常棘手。为什么qemu-arm在这个arm汇编代码中反复运行pthread_join?

主要功能是:

main: 
stmfd   sp!, {fp,lr} 

add    fp, sp, #4 
sub    sp, sp, #8 

sub    r3, sp, #8 
mov    r0, r3 
mov    r1, #0 
ldr    r2, .l_thrd1 
mov    r3, #0 
bl    pthread_create 

ldr r3, [fp, #-8] 
mov r0, r3 
mov r1, #0 
bl pthread_join 
... 

使用objdump的可以看到相关的反汇编代码:

00405468 <pthread_join>: 
    405468:  e5903068  ldr  r3, [r0, #104] ; 0x68 
    40546c:  e92d45f0  push {r4, r5, r6, r7, r8, sl, lr} 
    405470:  e3530000  cmp  r3, #0 
    405474:  e24dd014  sub  sp, sp, #20 
    405478:  e1a05000  mov  r5, r0 
    40547c:  e1a06001  mov  r6, r1 
    405480:  ba00004a  blt  4055b0 <pthread_join+0x148> 
    405484:  e590321c  ldr  r3, [r0, #540] ; 0x21c 
    .... 

它看起来正常,除非它引起了部分错误。该qemu.log看起来混乱和糟糕的解决此问题:

---------------- 
IN: pthread_join 
INST: isa=[0] opk=[JMP_OP] src={-,-,-,-} dst={-,-} shift={-,-,-} c=[1] s=[-] imm=[24,74] rotate_reg=[-] vfp={-,-,-,-} vfp_val={-,-,-,-} ### 
0x00405468: e5903068  ### ldr r3, [r0, #104] 
0x0040546c: e92d45f0  ### push  {r4, r5, r6, r7, r8, sl, lr} 
0x00405470: e3530000  ### cmp  r3, #0 ; 0x0 
0x00405474: e24dd014  ### sub  sp, sp, #20  ; 0x14 
0x00405478: e1a05000  ### mov  r5, r0 
0x0040547c: e1a06001  ### mov  r6, r1 
0x00405480: ba00004a  ### b.lt  0x4055b0 

---------------- 
IN: pthread_join 
INST: isa=[0] opk=[JMP_OP] src={-,-,-,-} dst={-,-} shift={-,-,-} c=[1] s=[-] imm=[24,74] rotate_reg=[-] vfp={-,-,-,-} vfp_val={-,-,-,-} ### 
0x00405468: e5903068  ### ldr r3, [r0, #104] 
0x0040546c: e92d45f0  ### push---------------- 
IN: start_thread 
INST: isa=[0] opk=[JMP_OP] src={-,-,-,-} dst={-,-} shift={-,-,-} c=[0] s=[-] imm=[24,4148] rotate_reg=[-] vfp={-,-,-,-} vfp_val={-,-,-,-} ### 
0x00404274: e7802003  ### str{r4, r5  , r6, r7r2, ,r8, sl[r0, , lrr3}] 
0x00405470: e3530000  ### 
.... 

显然,在pthread_join已经被输入两次。而第二次,'推'指令似乎还没有完全执行。寄存器也看起来很正常。我就是不明白。

另一个代码以正确的顺序运行。他们几乎相同的编码。

回答

0

没有人对这个问题得到答案。我必须亲自回答。

问题是由于堆栈指针(r13)被无意地保存在内存上而被另一个线程改变引起的。所以r13指向另一个内存地址并导致了段错误。