Assembly “我该如何解决?”;分段故障(堆芯倾倒)“;装配中?

Assembly “我该如何解决?”;分段故障(堆芯倾倒)“;装配中?,assembly,segmentation-fault,arm,armv8,Assembly,Segmentation Fault,Arm,Armv8,我正在使用ARMv8进行编码。我几乎完成了我的代码,只是遇到了一个问题。当我运行代码时,我得到了“分段错误(核心转储)”错误。 出现这个问题的原因是,当使用//THIS ONE A注释的行执行时,它将一个非常大的数字存储到x24中,而此时它应该存储一个介于0-50之间的数字。因此,在标有//this ONE B和C的行中,代码试图指向类似于x29+2^40的某个位置,而不是x29+(0-50) 我已经尝试通过代码查找错误的数字存储在I_的指针中的位置,但我找不到它。 我还尝试了将B行和C行中的x

我正在使用ARMv8进行编码。我几乎完成了我的代码,只是遇到了一个问题。当我运行代码时,我得到了“分段错误(核心转储)”错误。 出现这个问题的原因是,当使用//THIS ONE A注释的行执行时,它将一个非常大的数字存储到x24中,而此时它应该存储一个介于0-50之间的数字。因此,在标有//this ONE B和C的行中,代码试图指向类似于x29+2^40的某个位置,而不是x29+(0-50)

我已经尝试通过代码查找错误的数字存储在I_的指针中的位置,但我找不到它。 我还尝试了将B行和C行中的x24更改为x21的代码,它运行得非常好

最让我困惑的是,在代码中出现这个问题之前,testOut标记后面有一行几乎相同的代码。 唯一的区别是它在哪里工作,我将其存储到x21,在哪里不工作,它将存储到x24。从工作载荷到断裂载荷,Iu指向的值没有变化

注意:有问题的行位于代码底部附近

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
define(尺寸,50)
定义(v_base_r,x19)//索引0的堆栈位置
定义(ind_r,x20)//数组的索引
i_尺寸=4
j_尺寸=4
最小尺寸=4
温度大小=4
v_尺寸=50*4
alloc=-(16+i_尺寸+j_尺寸+最小尺寸+临时尺寸+v_尺寸)和-16
dealloc=-alloc
i_s=16
j_s=20
最小值=24
温度=28
v_s=32
fmt1:。字符串“v[%d]:%d\n”//i,v[i]
fmt2:.字符串“\n已删除的数组:\n”
fmt3:。字符串“v[%d]:%d\n”//i,v[i]
巴利格先生4
.全球主要
主要产品:stp x29、x30、[sp、alloc]!
mov x29,sp
添加v_base_r,x29,v_s
mov ind\u r,0//将索引初始化为0
从头算试验
初始化:
布莱兰
和w0,w0,0xFF
str w0,[v_base_r,ind_r,lsl2]//将当前rand()和&0xFF存储到v[ind_r]
adrp x0,fmt1
加上x0,x0,:lo12:fmt1
mov-x1,ind\u r
ldr w2[v_base_r,ind_r,lsl 2]
bl printf//打印“v[索引]:(索引处的值)”
为索引+1添加ind\u r,ind\u r,1//重复
初始测试:
cmp标识,尺寸
b、 lt init
mov x21,0
str x21,[x29,i_s]//将i初始化为0
b测试
forOut:
str x21,[x29,min_s]//x21仍然保存testOut中的i值
添加x22、x21、1
str x22[x29,j_s]//将j初始化为j=i+1
睾丸素
福林:
ldr x21,[x29,最小值]
ldr w23,[v_base_r,x22,lsl 2]//x22仍然存储testIn中j的值
ldr w24,[v_base_r,x21,lsl 2]//x23和x24将值存储在
//v[j]和v[min]
cmp w23,w24
b、 ge keep
str x22,[x29,min_s]//将j(x22)的值存储到min中
保持:
添加x22,x22,1//x22仍然存储j,因此我们可以增加
str x22,[x29,j_s]//然后存储为新的j以供下一次迭代使用
testIn:
ldr x22[x29,日本]
cmp x22,尺寸//j<尺寸
b、 福林上尉
ldr x21,[x29,最小值]
**ldr x24,[x29,i_s]**//这一个
ldr w23,[v_base_r,x21,lsl 2]
str w23[x29,temp\u s]//temp=v[min]
**ldr w23,[v_base_r,x24,lsl 2]**//这一个B
strw23[v_base_r,x21,lsl2]//v[min]=v[i]
ldr w23,[x29,温度]
**str w23[v_base_r,x24,lsl2]//v[i]=temp**///这一个C
添加x22,x22,1//x22仍然存储i,因此我们可以增加
str x22,[x29,i_s]//然后存储为新的i以供下一次迭代使用
测试结果:
ldr x21[x29,i_s]
cmp x21,尺寸为1//i<尺寸为1
b、 这是因为

这不是解决我的问题的最佳方法,但它对我很有效。 所以我猜当我给存储在堆栈上的每个变量分配空间时,我为每个整数分配了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_时,第二个十六进制代码在每次迭代中递增1。每次代码执行指令
strx22,[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。过度杀戮,但我不确定还需要做什么来修复它。

您好,在运行下面的代码时,我遇到了与分段错误(内核转储)相同的错误。:

**

**


解决方案:我更改了;调用内核int 0*80int 80h,这就清除了我的错误。

使用调试器的内存观察点功能捕捉对
i
@Jester的写入,我该怎么做?我使用的是gdb,I_s的值是16。显然,你不需要看
16
,你需要看实际地址-你可以从错误中看出,是
x29+16
@Jester我知道不仅仅是16。但是我是否要输入gdb
watch*$x29+16
watch$x29+16
或其他内容?这是我不知道的部分
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'