我是汇编程序的新手,我正在为ARM编程。 我正在制作一个带有两个子程序的程序:一个在内存中的字节向量上附加字节信息,另一个打印该向量。向量的第一个地址包含后面的元素数,最多255个。当我用GDB调试它时,我可以看到“appendbyte”子例程工作正常。但是当谈到“printvector”时,存在一些问题。首先,寄存器r1中加载的元素是错误的(当它应该为7时,它加载0)。然后,当我使用“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
和
bl printf
我希望我对这个问题很清楚。 提前谢谢!
答案 0 :(得分:2)
ARM ABI指定寄存器r0-r3和r12在函数调用时被视为易失性。意味着被调用者不必恢复其值。如果你使用bl,LR也会改变,因为LR将包含被调用函数的返回地址。
答案 1 :(得分:0)
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。你已经在ldr r1和循环后的cmp r2之间做了这个。现在b循环后的对齐是无害的,因为分支是无条件的,但同时没有必要,因为没有理由在那里对齐,汇编器正在生成指令流,因此字节不能是不对齐的。你在哪里使用.align是在说明之前的一些数据声明之后:
.byte 1,2,3,4,5,
.align
some_code_branch_dest:
特别是汇编程序抱怨或代码崩溃的地方。