Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arm 寄存器、臂组件中的Printf更改值_Arm_Printf_Cpu Registers - Fatal编程技术网

Arm 寄存器、臂组件中的Printf更改值

Arm 寄存器、臂组件中的Printf更改值,arm,printf,cpu-registers,Arm,Printf,Cpu Registers,我是装配编程新手,我是为ARM编程的。 我正在制作一个包含两个子例程的程序:一个在内存中的字节向量上附加一个字节信息,另一个打印这个向量。向量的第一个地址包含后面的元素数,最多255个。当我用GDB调试它时,我可以看到“appendbyte”子例程工作得很好。但是当涉及到“printvector”一个时,有一些问题。首先,寄存器r1中加载的元素是错误的(它加载0,而它应该是7)。然后,当我在使用“printf”函数后用GDB读取寄存器值时,很多寄存器得到了其他不应该更改的值,因为我没有修改它们,

我是装配编程新手,我是为ARM编程的。 我正在制作一个包含两个子例程的程序:一个在内存中的字节向量上附加一个字节信息,另一个打印这个向量。向量的第一个地址包含后面的元素数,最多255个。当我用GDB调试它时,我可以看到“appendbyte”子例程工作得很好。但是当涉及到“printvector”一个时,有一些问题。首先,寄存器r1中加载的元素是错误的(它加载0,而它应该是7)。然后,当我在使用“printf”函数后用GDB读取寄存器值时,很多寄存器得到了其他不应该更改的值,因为我没有修改它们,所以我只使用了“printf”。为什么“printf”要修改这些值

我在想一些关于对齐的事情。我不确定我是否正确使用了指令

以下是完整的代码:

    .text
    .global main    
    .equ    num, 255    @ Max number of elements

main:
    push    {lr}

    mov r8, #7
    bl appendbyte
    mov r8, #5
    bl appendbyte
    mov r8, #8
    bl appendbyte
    bl imprime

    pop {pc}

.text
.align  

printvector:
    push {lr}

    ldr r3, =vet @ stores the address of the start of the vector in r3
    ldr r2, [r3], #1 @ stores the number of elements in r2

.align  
loop:
    cmp r2, #0 @if there isn't elements to print
    beq fimimprime @quit subroutine
    ldr r0, =node   @r0 receives the print format
    ldr r1, [r3], #1 @stores in r1 the value of the element pointed by r3. Increments r3 after that.
    sub r2, r2, #1 @decrements r2 (number of elements left to print)
    bl printf @call printf
    b loop @continue on the loop

.align  
endprint:
    pop {pc}

.align  
appendbyte:
    push {lr}

    ldr r0, =vet    @stores in r0 the beggining address of the vector
    ldr r1, [r0], #1    @stores in r1 the number of elements and makes r0 point to the next address
    add r3, r0, r1  @stores in r3 the address of the first available position
    str r8, [r3]    @put the value at the first available position
    ldr r0, =vet    @stores in r0 the beggining address of the vector
    add r1, r1, #1  @ increment the number of elements in the vector
    str r1, [r0]    @ stores it in the vector

    pop {pc}

.data           @ Read/write data follows
.align          @ Make sure data is aligned on 32-bit boundaries
vet:    .byte 0
    .skip   num     @ Reserve num bytes

.align
node:   .asciz "[%d]\n"

.end
问题就在这里

    ldr r1, [r3], #1

我希望我对这个问题很清楚。
提前谢谢

ARM ABI指定寄存器r0-r3和r12在函数调用时被视为易失性的。这意味着被调用方不必恢复其值。如果使用bl,LR也会改变,因为LR将包含被调用函数的返回地址

更多信息可在ARM信息中心条目或(ARM程序调用标准)文档中找到

printvector:
    push {lr}

    ldr r3, =vet @ stores the address of the start of the vector in r3
    ldr r2, [r3], #1 @ stores the number of elements in r2

.align  
loop:
    cmp r2, #0 @if there isn't elements to print
    beq fimimprime @quit subroutine
    ldr r0, =node   @r0 receives the print format
    ldr r1, [r3], #1 @stores in r1 the value of the element pointed by r3. Increments r3 after that.
    sub r2, r2, #1 @decrements r2 (number of elements left to print)
    bl printf @call printf
    b loop @continue on the loop

.align  
endprint:
    pop {pc}
这绝对不是使用align的方式。Align是用来对齐某个边界(在可选参数中指定,注意这是一个汇编指令,而不是一条指令)后面的内容,方法是用零或任何填充来填充二进制文件。因此,您不希望在指令之间的代码流中出现.align。您已经在ldr r1和cmp r2 after循环之间完成了此操作。现在,在b之后对齐循环是无害的,因为分支是无条件的,但同时没有必要,因为没有理由在那里对齐,汇编程序正在生成指令流,因此字节不能不对齐。使用.align的位置是在一些数据声明之后,在说明之前:

.byte 1,2,3,4,5,
.align
some_code_branch_dest:

特别是在汇编程序抱怨或代码崩溃的情况下。

谢谢,我了解了函数调用如何编辑r0-r3,以及如何使用r4和r5作为变量寄存器,尽管我仍然无法从向量的Andress中只加载零值。谢谢谢谢你帮我澄清这件事,我真的对此表示怀疑。谢谢
.byte 1,2,3,4,5,
.align
some_code_branch_dest: