如何在汇编中修复 "Segmentation fault (core dumped)"?
How do I fix "Segmentation fault (core dumped)" in assembly?
我正在使用 ARMv8 进行编码。我几乎完成了我的代码,除了我 运行 遇到了问题。当我 运行 代码时,我得到 "Segmentation fault (core dumped)" 错误。
出现此问题是因为当执行注释为 //THIS ONE A 的行时,它会将一个非常大的数字存储到 x24 中,而它应该存储一个介于 0-50 之间的数字。因此,在标记为 //THIS ONE B 和 C 的行中,代码试图指向类似 x29 + 2^40 左右的位置,而不是 x29 + (0-50).
我已尝试通过代码查找 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
这不是解决我的问题的最佳方法,但它对我有用。
所以我想当我将 space 赋给存储在堆栈中的每个变量时,我为每个整数分配了 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 之间,我将 j_s 递增 1,循环运行 50 次。当我使用 x/4x $x29+16
检查 i_s 时,第二个十六进制代码在每次迭代时递增 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
所以我最终将分配给每个整数的大小从 4 更改为 8。太过分了,但我不确定还能做些什么来解决它。
您好,当 运行 下面的代码时,我遇到了 分段错误(核心已转储) 的相同错误:
**
section .text
global _start
_start: ;tells linker the entry point
mov edx, len ;message length
mov ecx, msg ;message wo write
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number(sys_write)
int 0*80 ;call kernel
mov edx, 9 ;message length
mov ecx, s2 ;message to write
mov ebx, 1 ;file descriptor(stdout)
mov eax, 4 ;system call number (sys_write)
int 0*80 ;call kernel
mov eax, 1 ;system call number (sys_Exit)
int 0*80 ;call kernel
section .data
msg db 'Dispay 9 stars', 0xa ;a message
len equ $ - msg ;length of message
s2 times 9 db 'x'
**
解决方案:我将 ;call kernel 从 int 0*80 更改为 int 80h 这清除了我的错误。
我正在使用 ARMv8 进行编码。我几乎完成了我的代码,除了我 运行 遇到了问题。当我 运行 代码时,我得到 "Segmentation fault (core dumped)" 错误。 出现此问题是因为当执行注释为 //THIS ONE A 的行时,它会将一个非常大的数字存储到 x24 中,而它应该存储一个介于 0-50 之间的数字。因此,在标记为 //THIS ONE B 和 C 的行中,代码试图指向类似 x29 + 2^40 左右的位置,而不是 x29 + (0-50).
我已尝试通过代码查找 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
这不是解决我的问题的最佳方法,但它对我有用。 所以我想当我将 space 赋给存储在堆栈中的每个变量时,我为每个整数分配了 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 之间,我将 j_s 递增 1,循环运行 50 次。当我使用 x/4x $x29+16
检查 i_s 时,第二个十六进制代码在每次迭代时递增 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
所以我最终将分配给每个整数的大小从 4 更改为 8。太过分了,但我不确定还能做些什么来解决它。
您好,当 运行 下面的代码时,我遇到了 分段错误(核心已转储) 的相同错误:
**
section .text
global _start
_start: ;tells linker the entry point
mov edx, len ;message length
mov ecx, msg ;message wo write
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number(sys_write)
int 0*80 ;call kernel
mov edx, 9 ;message length
mov ecx, s2 ;message to write
mov ebx, 1 ;file descriptor(stdout)
mov eax, 4 ;system call number (sys_write)
int 0*80 ;call kernel
mov eax, 1 ;system call number (sys_Exit)
int 0*80 ;call kernel
section .data
msg db 'Dispay 9 stars', 0xa ;a message
len equ $ - msg ;length of message
s2 times 9 db 'x'
**
解决方案:我将 ;call kernel 从 int 0*80 更改为 int 80h 这清除了我的错误。