私は自分のコーディングに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
デバッガのメモリウォッチポイント機能を使用して、 'i_s'への書き込みをキャッチします。 – Jester
@Jesterどうすればいいですか?私はgdbを使用しており、i_sの値は16です –
あなたは明らかに '16'を見ないでください、あなたは実際のアドレスで時計が必要です - あなたはフォールトからそれを読むことができます、それは' x29 + 16'です – Jester