0

调试以下代码时遇到问题:

// create format strings
fmt1:   .string     "Initial pyramid values:\n"
fmt2:   .string     "Pyramid %s origin = (%d, %d)\n"
fmt3:   .string     "\tBase width = %d Base length = %d\n"
fmt4:   .string     "\tHeight = %d\n"
fmt5:   .string     "\tVolume = %d\n"
fmt6:   .string     "\nChanged pyramid values:\n"

fmtfir: .string     "first"
fmtsec: .string     "second"

    .balign 4   // ensures alignment of instructions
    .global main    // executes starting label

    // macro defines
    define(FALSE, 0)
    define(TRUE, 1)

    // assembler equates for structs
    point_x = 0     // point, int x
    point_y = 4     // point, int y

    dimension_width = 0 // dimension, int width
    dimension_length = 4    // dimension, int length

    pyramid_origin = 0  // pyramid, point origin
    pyramid_base = 8    // pyramid, dimension base
    pyramid_height = 16 // pyramid, int height
    pyramid_volume = 20 // pyramid, int volume

    // main: memory allocation and offsets
    first_size = 24
    second_size = 24
    alloc = -(16 + first_size + second_size) & -16
    dealloc = -alloc
    first_s = 16
    second_s = 40

    // newPyramid: memory allocation and offsets
    define(p_base_r, x15)
    p_size = 24
    falloc = -(16 + p_size) & -16
    fdealloc = -falloc
    p_s = 16

// struct pyramid newPyramid()
// initializes a struct pyramid p and returns it
newPyramid:
    stp x29, x30, [sp, falloc]!             // saves FP and LR registers
    mov x29, sp                     // update sp

    // initialize attributes of struct pyramid p
    add p_base_r, x29, p_s
    str xzr, [p_base_r, pyramid_origin + point_x]       // p.origin.x = 0
    str xzr, [p_base_r, pyramid_origin + point_y]       // p.origin.y = 0
    mov w9, 2
    str w9, [p_base_r, pyramid_base + dimension_width]  // p.base.width = 2
    mov w10, 2
    str w10, [p_base_r, pyramid_base + dimension_length]    // p.base.length = 2
    mov w11, 3
    str w11, [p_base_r, pyramid_height]         // p.height = 3

    // calculate volume
    mul w9, w9, w10
    mul w9, w9, w11
    sdiv w9, w9, w11
    str w9, [p_base_r, pyramid_volume]          // p.volume = 2*2*3/3

    // store attributes of p into address at x8
    ldr w9, [p_base_r, pyramid_origin + point_x]        // w9 = p.origin.x
    str w9, [x8, pyramid_origin + point_x]
    ldr w9, [p_base_r, pyramid_origin + point_y]        // w9 = p.origin.y
    str w9, [x8, pyramid_origin + point_y]

    ldr w9, [p_base_r, pyramid_base + dimension_width]  // w9 = p.base.width
    str w9, [x8, pyramid_base + dimension_width]
    ldr w9, [p_base_r, pyramid_base + dimension_length] // w9 = p.base.length
    str w9, [x8, pyramid_base + dimension_length]
    ldr w9, [p_base_r, pyramid_height]          // w9 = p.height
    str w9, [x8, pyramid_height]
    ldr w9, [p_base_r, pyramid_volume]          // w9 = p.volume
    str w9, [x8, pyramid_volume]

    ldp x29, x30, [sp], fdealloc                // deallocate memory
    ret                         // return

// void printPyramid(char *name, struct pyramid *p)
// print out the pyramid's attributes
printPyramid:
    stp x29, x30, [sp, falloc]!
    mov x29, sp

    // store parameters x0, x1
    mov x9, x0      // x9 = *name
    mov p_base_r, x1    // x15 = *p

    // print name and origin of pyramid
    adrp x0, fmt2
    add x0, x0, :lo12:fmt2
    mov x1, x9
    ldr w2, [p_base_r, pyramid_origin + point_x]
    ldr w3, [p_base_r, pyramid_origin + point_y]
    bl printf

    // print pyramid base width, length
    adrp x0, fmt3
    add x0, x0, :lo12:fmt3
    ldr w1, [p_base_r, pyramid_origin + point_x]
    ldr w2, [p_base_r, pyramid_origin + point_y]
    bl printf

    // print pyramid height
    adrp x0, fmt4
    add x0, x0, :lo12:fmt4
    ldr w1, [p_base_r, pyramid_height]
    bl printf

    // print pyramid volume
    adrp x0, fmt5
    add x0, x0, :lo12:fmt5
    ldr w1, [p_base_r, pyramid_volume]
    bl printf

    ldp x29, x30, [sp], fdealloc
    ret

main:
    stp x29, x30, [sp, alloc]!      // saves FP and LR registers
    mov x29, sp             // update sp

    // initialize pyramid first, second
    add x8, x29, first_s
    bl newPyramid
    //add x8, x29, second_s
    //bl newPyramid

    // print out "Initial pyramid values:\n"
    adrp x0, fmt1
    add x0, x0, :lo12:fmt1
    bl printf

    // printPyramid("first", &first)
    adrp x0, fmtfir
    add x0, x0, :lo12:fmtfir
    add x1, x29, first_s
    bl printPyramid

done:   mov x0, 0
    ldp x29, x30, [sp], dealloc
    ret

printPyramid 标签中的 printf 语句会出现问题:也就是说,当以下行运行时:

// print name and origin of pyramid
adrp x0, fmt2
add x0, x0, :lo12:fmt2
mov x1, x9
ldr w2, [p_base_r, pyramid_origin + point_x]
ldr w3, [p_base_r, pyramid_origin + point_y]
bl printf

// print pyramid base width, length (I've adjusted this
// for debugging purposes to use the same arguments as above)
adrp x0, fmt3
add x0, x0, :lo12:fmt3
ldr w1, [p_base_r, pyramid_origin + point_x]
ldr w2, [p_base_r, pyramid_origin + point_y]
bl printf

第一个 printf 语句可以很好地打印出原点,输出“Pyramid first origin: (0, 0)”。

然而,第二个 printf 语句在参数中打印出一个随机的整数字符串,我不知道为什么会这样,因为我提供了与 w1、w2 中的参数相同的确切地址。

任何帮助将不胜感激。谢谢。

4

0 回答 0