2017-03-03 5 views
0

私は自分のコーディングにARMv8を使用しています。私は問題に遭遇したことを除いて、ほとんど私のコードを完了しています。コードを実行すると、「セグメンテーションフォルト(コアダンプされた)」というエラーが表示されます。 この問題は、// THIS ONE Aでコメントされた行が実行されるときに、0から50までの数を格納する必要があるときに非常に大きな数をx24に格納するために発生します。このため、//この1つのBとCというラベルの行では、x29 +(0-50)の代わりにx29 + 2^40程度の場所を指し示します。アセンブリで「セグメンテーションフォルト(コアダンプ)」を修正するにはどうすればよいですか?

私は、間違った番号がi_sポインタに格納されている場所を見つけるためにコードを調べてみましたが、見つけられませんでした。 私はまた、線BとCのx24をx21に変更してコードを試しましたが、それは完全に正常に動作します。

私を最も混乱させる部分は、コード内のこの号の前に、testOutタグの直後にほぼ同じコード行があることです。 唯一の違いは、動作する場所、x21に格納する場所、動作しない場所、x24に格納する場所です。また、i_sが作業負荷から壊れた負荷に指す値に変更はありません。

注:問題の行は、コード

define(SIZE, 50) 
define(v_base_r, x19)  //stack location of index 0 
define(ind_r, x20)  //index of array 

i_size = 4 
j_size = 4 
min_size = 4 
temp_size = 4 
v_size = 50*4 
alloc = -(16+i_size+j_size+min_size+temp_size+v_size) & -16 
dealloc = -alloc 

i_s = 16 
j_s = 20 
min_s = 24 
temp_s = 28 
v_s = 32 

fmt1:  .string "v[%d]: %d\n"  //i, v[i] 

fmt2:  .string "\nSorted array:\n" 

fmt3:  .string "v[%d]: %d\n"  //i, v[i] 
    .balign 4 

    .global main 

main:  stp x29, x30, [sp, alloc]! 

    mov x29, sp 

    add v_base_r, x29, v_s 
mov ind_r, 0   //initialize index to 0 
     b inittest 
init: 
     bl rand 
     and w0, w0, 0xFF 
     str w0, [v_base_r, ind_r, lsl 2]//stores current rand()&&0xFF into v[ind_r] 

     adrp x0, fmt1 
     add x0, x0, :lo12:fmt1 
     mov x1, ind_r 
     ldr w2, [v_base_r, ind_r, lsl 2] 

     bl printf   //Printing "v[index]: (value at index)" 

     add ind_r, ind_r, 1  //repeats for index + 1 

inittest: 
     cmp ind_r, SIZE 
     b.lt init 
mov x21, 0 

    str x21, [x29, i_s]  //initialize i to 0 

    b testOut 
forOut:  
     str x21, [x29, min_s]  //x21 is still holding the value of i from testOut 
     add x22, x21, 1 
     str x22, [x29, j_s]  //initialize j as j = i+1 


    b testIn 
forIn:  
     ldr x21, [x29, min_s] 
     ldr w23, [v_base_r, x22, lsl 2] //x22 still stores value of j from testIn 
     ldr w24, [v_base_r, x21, lsl 2] //x23 and x24 store values in 
          //v[j] and v[min], respectively 
     cmp w23, w24 
     b.ge keep 

    str x22, [x29, min_s]  //value of j (x22) is stored into min 
keep:  
     add x22, x22, 1   //x22 still stores j, so we can increment 
     str x22, [x29, j_s]  //and then store as new j for next iteration 
testIn:  
     ldr x22, [x29, j_s] 
     cmp x22, SIZE   //j < SIZE 

    b.lt forIn 

    ldr x21, [x29, min_s] 

    **ldr x24, [x29, i_s]**  //THIS ONE A 

    ldr w23, [v_base_r, x21, lsl 2] 
    str w23, [x29, temp_s]  //temp = v[min] 

    **ldr w23, [v_base_r, x24, lsl 2]**  //THIS ONE B 

    str w23, [v_base_r, x21, lsl 2] //v[min] = v[i] 
    ldr w23, [x29, temp_s] 

    **str w23, [v_base_r, x24, lsl 2] //v[i] = temp**  //THIS ONE C 

    add x22, x22, 1   //x22 still stores i, so we can increment 
    str x22, [x29, i_s]  //and then store as new i for next iteration 
testOut:  
     ldr x21, [x29, i_s] 
     cmp x21, SIZE-1   //i < SIZE-1 
     b.lt forOut 
+1

デバッガのメモリウォッチポイント機能を使用して、 'i_s'への書き込みをキャッチします。 – Jester

+0

@Jesterどうすればいいですか?私はgdbを使用しており、i_sの値は16です –

+0

あなたは明らかに '16'を見ないでください、あなたは実際のアドレスで時計が必要です - あなたはフォールトからそれを読むことができます、それは' x29 + 16'です – Jester

答えて

0

の底部付近にあるこれは私の問題を解決する最良の方法はありませんが、それは私のために働きました。 私はスタックに格納していた各変数にスペースを与えたとき、各整数につき4つを割り当てたと思います。したがって、次のコード:

i_size = 4 
j_size = 4 
min_size = 4 
temp_size = 4 
v_size = 50*4 
alloc = -(16+i_size+j_size+min_size+temp_size+v_size) & -16 
dealloc = -alloc 

i_s = 16 
j_s = 20 
min_s = 24 
temp_s = 28 
v_s = 32 

i_sからの2つの読み取りの間で、私は50回実行するループでj_sを1増加させます。 x/4x $x29+16を使用してi_sを調べると、2回目の16進コードが各反復で1ずつ増加しました。これは、コードが命令str x22, [x29, j_s]を実行するたびに増加し、これにより私は何が間違っていたのかを認識しました。

i_size = 8 
j_size = 8 
min_size = 8 
temp_size = 8 
v_size = 50*4 
alloc = -(16+i_size+j_size+min_size+temp_size+v_size) & -16 
dealloc = -alloc 

i_s = 16 
j_s = 24 
min_s = 32 
temp_s = 40 
v_s = 48 

ので、私は8オーバーキルに4から各整数に割り当てられたサイズを変更してしまった:私はこれに、コードの先頭ブロックを変更したことだった、最後に私の問題を修正することになった何

しかし、私はそれを修正するために何をすべきか分からない。

関連する問題