2

我正在使用 ARMv8 进行编码。我几乎完成了我的代码,除了我遇到了问题。当我运行代码时,我收到“分段错误(核心转储)”错误。问题的出现是因为当用 //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
4

2 回答 2

1

您好,在运行以下代码时,我遇到了同样的分段错误(核心转储)错误:

**

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 内核int 0*80更改为int 80h,这清除了我的错误。

于 2019-09-15T07:31:58.063 回答
1

这不是解决我的问题的最佳方法,但它对我有用。所以我想当我为存储在堆栈中的每个变量分配空间时,我为每个整数分配了 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 次。当我使用第二个十六进制代码检查 i_s 时x/4x $x29+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

所以我最终将分配给每个整数的大小从 4 更改为 8。矫枉过正,但我​​不确定还能做些什么来修复它。

于 2017-03-06T01:00:59.373 回答