1

我正在 Linux ARM 和 FreeBSD ARM 中进行一些汇编编程。我有一些关于 ARM 管道和汇编编程的问题......

Q1。假设有ARM汇编指令(ARM模式)如

add r0, pc, #0
mov r1, #1
mov r1, #2
mov r1, #3
mov r1, #4

当这些被执行时,r0 的值是多少?为什么?

Q2。假设有手臂组装说明,例如

sub r0, r0, r0    
sub r1, r1, r1
svc #?(a system call which never returns such as execve)
mov r2, #1
mov r3, #1

假设svc永远不会返回,是否mov r2, #1执行?(因为流水线执行...?)

Q3。Q1、Q2 的结果在 Thumb 模式下是否相同?或不?为什么?

Q4,在 FreeBSD 中,Thumb 模式的 svc 编号是否与 ARM 模式不同? svc $0x3b(execve) 在 ARM 模式下工作正常,但在 Thumb 模式下不起作用。例如:

mov r7, $0x3b
svc 1

这告诉我“错误的系统调用”

4

2 回答 2

4

流水线效应已在第一个 ARM 体系结构版本中明确公开。从那时起,管道发生了变化,但为了兼容性,PC 寄存器的值被保留了:

  1. 在 ARM 模式下,读取PC返回当前指令的地址加上8(即前面两条 ARM 指令)。BL这允许在引入指令之前使用的原始调用序列:

      MOV LR, PC  ; LR gets loaded with address of "retaddr"
      MOV PC, R2  ; jump to adddress in R2
    retaddr:
      ; "MOV PC, LR" returns here
    
  2. 在 Thumb 模式下,读取PC当前指令的返回地址加4(即前面两条 16 位 Thumb 指令)。即使在允许 32 位指令的 Thumb-2 中,这种行为也保持不变。

这可以通过阅读 ARM 架构手册来确认:

(来自 B1.3 ARM 处理器模式和 ARM 核心寄存器)

// R[] - non-assignment form
// =========================
bits(32) R[integer n]
  assert n >= 0 && n <= 15;
  if n == 15 then
    offset = if CurrentInstrSet() == InstrSet_ARM then 8 else 4;
    result = _R[RName_PC] + offset;
  else
    result = Rmode[n, CPSR.M];
  return result;

现在,回答您的问题:

Q1:r0将得到add指令地址加 8
Q2:可能不会,但即使确实被执行(在具有推测执行的处理器中),当执行进入svc处理程序时,它的结果也会被丢弃。所以从程序员的角度来看,mov r2, #1没有执行
Q3:在 Q1 中,r0会得到add指令地址加 4。Q2 得到相同的答案。
Q4:如前所述,它与管道无关,因此最好作为一个单独的问题提出。

于 2013-07-24T11:33:13.087 回答
0

由于流水线是透明地发生的,因此您大部分时间都不需要担心它,除非您正在优化代码或使用 r15/pc 寄存器。

  1. 如果我没记错的话, r0 应该包含mov r1, #2指令的地址(前面两条指令)。
  2. 不,如果系统调用没有返回,它就不会执行。为什么要呢?
  3. 它应该是相似的。

您应该能够通过简单地在调试器中运行您的示例代码来确认我的大部分答案。

于 2013-07-24T10:50:17.613 回答