相关疑难解决方法(0)

什么是被调用者和调用者保存的寄存器?

我在理解调用者和被调用者保存的寄存器之间的区别以及何时使用什么方面遇到了一些麻烦.

我使用的是MSP430:

程序:

mov.w #0,R7 
mov.w #0,R6 
add.w R6,R7 
inc.w R6 
cmp.w R12,R6 
jl l$loop 
mov.w R7,R12
ret
Run Code Online (Sandbox Code Playgroud)

上面的代码是被调用者,并且在教科书示例中使用,因此它遵循惯例.R6和R7被呼叫者保存,R12被呼叫者保存.我的理解是被调用者保存的regs不是"全局的",因为在过程中改变它的值不会影响它在程序之外的值.这就是您必须在开头将新值保存到被调用者注册表中的原因.

R12,保存的来电者是"全球性的",因为缺乏更好的词汇.该程序在通话后对R12产生持久影响.

我的理解是否正确?我错过了其他的东西吗?

assembly abi cpu-registers calling-convention

40
推荐指数
3
解决办法
8万
查看次数

ARM:链接寄存器和帧指针

我试图理解链接寄存器和帧指针在ARM中是如何工作的.我去过几个网站,我想确认一下我的理解.

假设我有以下代码:

int foo(void)
{
    // ..
    bar();
    // (A)
    // ..
}

int bar(void)
{
    // (B)
    int b1;
    // ..
    // (C)
    baz();
    // (D)
}

int baz(void)
{
    // (E)
    int a;
    int b;
    // (F)
}
Run Code Online (Sandbox Code Playgroud)

我叫foo().将链接寄存器包含在点(A)的地址码和帧指针包含在代码点(B)的地址?在声明了所有本地人之后,堆栈指针可以是bar()内的任何位置吗?

[编辑]添加了另一个函数调用baz()

c arm

28
推荐指数
1
解决办法
5万
查看次数

ARM到C调用约定,NEON寄存器保存

有一个类似的帖子涵盖了常规寄存器.NEON寄存器怎么样?据我记得,函数调用必须保留上半部分或下半部分寄存器.我无法在任何地方找到这些信息,有人可以澄清一下吗?

谢谢

AAPCS,§5.1.1核心寄存器:

  • r0-r3是参数和临时寄存器; r0-r1也是结果寄存器
  • r4-r8是被调用者保存寄存器
  • r9可能是一个被调用者保存寄存器(在AAPCS的某些变体上它是一个特殊的寄存器)
  • r10-r11是被调用者保存寄存器
  • r12-r15是特殊寄存器

AAPCS,§5.1.2.1VFP寄存器使用约定(VFP v2,v3和高级SIMD扩展):

  • 必须保留s16-s31(d8-d15,q4-q7)
  • s0-s15(d0-d7,q0-q3)d16-d31(q8-q15)不需要保留

arm abi neon

14
推荐指数
1
解决办法
5015
查看次数

Android CPU注册名称?

此代码片段是从Samsung Tab S上的Android崩溃报告中提取的:

Build fingerprint: 'samsung/chagallwifixx/chagallwifi:5.0.2/LRX22G/T800XXU1BOCC:user/release-keys'
Revision: '7'
ABI: 'arm'
    r0 a0d840bc  r1 a0dcb880  r2 00000001  r3 a0d840bc
    r4 a0dc3c4c  r5 00000000  r6 a066d200  r7 00000000
    r8 32d68f40  r9 a0c359a8  sl 00000014  fp bef3ba84
    ip a0dc3fb8  sp bef3ba10  lr a0c35a0c  pc a0c34bc8  cpsr 400d0010
Run Code Online (Sandbox Code Playgroud)

r0通过r9非常清楚的通用寄存器,sp(r13)是堆栈指针,pc(r15)是程序计数器(指令指针).参考维基百科的ARM体系结构页面寄存器部分(我查看的许多页面之一),我发现lr(r14)是链接寄存器,并且cpsr是"当前程序状态寄存器".

我想知道what sl(r10),fp(r11)和ip(r12)是什么.我想到ip …

android arm computer-architecture cpu-registers

6
推荐指数
1
解决办法
3715
查看次数

WinCE 和 Linux 上的 ARM 调用约定?

WinCE 和 Linux 在 ARM 上使用相同的调用约定吗?有什么区别?

到目前为止,我发现的文件并没有很好地解释。例如,在http://msdn.microsoft.com/en-us/library/ms864497.aspx 上,一行显示“Windows CE .NET 编译器”,下一行显示“ARM 编译器”,而“CLARM " 在底部,并不清楚它是指相同的编译器还是不同的编译器。这是我迄今为止发现的......

  • ARM 调用序列规范(WinCE) - 写得不好的文档
  • ARM 到 C 调用约定(Linux) - 非正式解释
  • 维基百科- 没有指定操作系统,也没有说明如何处理结构、浮点数或 64 位数字,也没有说明额外参数放在哪里以防它们不适合寄存器。
  • 更新:ARM 体系结构的过程调用标准- 最后我找到了一个全面的文档,但它没有说明哪些操作系统遵循标准(或者这些操作系统可能施加哪些变体或附加约束)。

我问的原因是我想尝试在 WinCE 中使用 LLVM 在运行时生成一些简单的代码,但它只正式支持 Linux。

linux arm calling-convention windows-ce

5
推荐指数
1
解决办法
1704
查看次数

什么是ARM本机代码调用约定?

我在Visual Studio C++使用的ARM调用约定上找不到任何关于Windows RT的文档.微软是否使用ARM的AAPCS

如果Microsoft在ARM上使用AAPCS/EABI for Windows RT,它是否也使用ARM的C++ ABI(源自Itanium C++ ABI)?也许甚至ARM异常处理ABI

Windows RT上ARM使用的调用约定是否与其他(嵌入式)ARM Windows变体使用的约定不同?

有没有可靠的方法通过预定义的编译器宏检测ARM上的Windows RT?

更新:添加了有关C++ ABI的问题.

c++ winapi arm calling-convention windows-runtime

4
推荐指数
1
解决办法
1508
查看次数

ARM 中暂存寄存器的用例是什么?

为什么我们在 ARM 架构中有一个临时寄存器?处理器如何使用它,我的意思是这个寄存器的目的是什么?

arm abi

2
推荐指数
2
解决办法
1647
查看次数

为什么在具有相似版本gcc的X86和arm中,相同结构的大小计算不同?

正如主题所说,我得到了计算相同结构的同一操作的不同结果。结构如下。

struct test
{
  char m1;
  double d1;
}
Run Code Online (Sandbox Code Playgroud)

在Linux的gcc-4.6.3和gcc-4.2中使用sizeof(struct test)计算时,得到的结果为“ 12”。当我在Linux中使用gcc-4.6.1在WinXP中使用VC 6.0时,得到的结果为“ 16”。所以我很困惑,为什么会这样?GCC如何计算结构的大小?

添加:

如答案所示,arm linux需要AAPCS定义的8字节对齐,但是为什么x86中的vc 6.0会得到结果“ 16”?有人使用vc 2003或更高版本来计算吗?

C标准(例如C89 / C99)还定义了什么?

c linux gcc arm visual-c++

1
推荐指数
1
解决办法
1481
查看次数

从 ARM 汇编到 C 的函数调用的参数传递约定

我有一个 C 代码,它调用 ARM Assembly 中定义的函数。必须传递两个参数。

如果函数调用如下所示:

functionName(a, b)
Run Code Online (Sandbox Code Playgroud)

寄存器x0并按x1什么顺序保存这些值?是x0一直持有a还是一直x1持有b,还是相反?

c assembly arm parameter-passing

1
推荐指数
1
解决办法
4237
查看次数

Arm Assembly 在子程序中推送 POP 链接寄存器和 pc 并在子程序中调用子程序的正确方法

用于 ARM 组装

我一直在我的子程序中执行以下操作:

SubRoutine:
  PUSH {r1,r2,lr}
  //code that changes r1 and r2
  POP {r1,r2,lr}
  bx lr
Run Code Online (Sandbox Code Playgroud)

这是从子程序返回并继续执行主函数中代码的正确方法吗?我看到周围的人正在做以下事情:

SubRoutine:
  PUSH {r1,r2,lr}
  //code that changes r1 and r2
  POP {r1,r2,pc}
  bx lr
Run Code Online (Sandbox Code Playgroud)

但我不知道为什么你在推 LR 时会 POP 电脑。哪个是正确的方法,为什么?

此外,如果您在子例程中调用子例程,请执行以下操作:

SubRoutine:
   PUSH {r1,r2,lr}

  //code that changes r1 and r2
  PUSH {lr}
  bl AnotherRoutine (where bx lr will be used to return from it)
  POP {lr}

  POP {r1,r2,pc}
  bx lr
Run Code Online (Sandbox Code Playgroud)

或者你是这样做的:

SubRoutine:
   PUSH {r1,r2,lr}

  //code that changes r1 and r2
  PUSH {lr}
  bl AnotherRoutine(where …
Run Code Online (Sandbox Code Playgroud)

assembly stack arm subroutine

1
推荐指数
1
解决办法
4142
查看次数

使用gcc和as编译汇编之间有什么区别

我正在学习如何使用汇编语言(顺便说一句在Raspberry Pi上),并且想知道使用gccas进行编译之间有什么区别。

到目前为止,我注意到的差异是:

  • 我应该使用做额外的链接步骤as
  • 在Raspberry Pi上,as似乎比单独识别要好gccgcc在使用整数除法之类的指令之前,我必须告诉架构。
  • 随着gcc我可以很方便地在C标准库函数。我认为可以使用,as但我还没有弄清楚。

我想坚持使用特定的编译器。我应该知道还有什么其他区别。使用这两种方法都有优点/缺点吗?

assembly gcc gnu-assembler raspberry-pi

1
推荐指数
1
解决办法
59
查看次数