【发布时间】:2017-05-25 10:45:42
【问题描述】:
我从教授那里得到了以下 ARM 汇编代码。 我不明白为什么我需要将堆栈指针移动到 r1 以及究竟会发生什么。
我从讲座中知道,...
堆栈指针指向堆栈上最后写入的值。
指向总是意味着存储地址吗? 我设法让代码工作。但我想提高代码质量并了解发生了什么。我也不允许在程序的任何地方使用算术运算。 我也试过调试器。但我只知道如何从那里观看节目计数器。 我用过
info registers sp pc
和
disas
我搜索了调试器的所有选项,但找不到有用的东西。
在堆栈指针寄存器中存储-我猜-一些地址值。
// scan for users answer 'y'
ldr r0, =charplace
mov r1, sp @ ???
bl scanf @ Scan user's answer
ldr r1, =yes @ Put address of 'y' in r1
ldrb r1, [r1] @ Load the actual character 'y' into r1
在主函数开始时我这样做:
.global main
main:
push {r4 - r7, lr} @ copy values of these reg on top of the stack
sub sp, sp, #4 @ needs to be replaced ! TODO
最后是这样的:
end: add sp, sp, #4 @ needs to be replaced ! TODO
pop {r4 - r7, pc} @ copy values from the top of the stack back into these registers
【问题讨论】:
-
可以通过注释掉
add/sub并更改有关push/pop指令的某些内容来解决 TODO。如果你的调试器恰好是gdb,你可以试试layout asmlayout regs,虽然我不确定它是否能在你的目标平台上工作。 -
是的,
sp寄存器中的值通常是内存中的有效地址,它是为“堆栈”保留的(它只是普通内存和指向它的指针,push/pop功能可以排序原则上通过将值存储/加载到内存+更新指针来模拟,push/pop写起来更短,而且它们通常是原子的(或者至少更容易通过某种lock前缀使它们成为原子)) -
好的。感谢您的提示。我试过
layout asmlayout regs。它一开始看起来不错,但在短时间内就坏了。我不知道要更改说明。这就是我问的原因。 :3 -
好吧,如果您了解
push/pop与多个寄存器的工作原理,您一定会弄清楚如何使它们也对sp执行额外的+-4。虽然它不是add/sub的完全替代品,因为它会产生额外的副作用,所以您还必须考虑使用调用约定,考虑哪种调整会产生无害的副作用。只需查看 ARM 文档以了解这些指令的详细信息,并想象它们是如何工作的,以及sp和其他寄存器会发生什么。 -
main.s: Assembler messages: main.s:22: Warning: if writeback register is in list, it must be the lowest reg in the list main.s:144: Warning: writeback of base register when in register list is UNPREDICTABLE
标签: pointers assembly arm raspberry-pi3