如何使用C语言获取asm变量值?

时间:2019-01-04 15:00:28

标签: c cortex-m firmware cortex-m3

现在,我正在尝试了解CM3固件代码。 但尤其是我发现其中一些代码是由以下asm代码组成的, asm code

// Uart string output 
void UartPuts(unsigned char * mytext)
{
  unsigned char CurrChar;
  do {
    CurrChar = *mytext;
    if (CurrChar != (char) 0x0) {
      UartPutc(CurrChar);  // Normal data
      }
    *mytext++;
  } while (CurrChar != 0); 
  return;
}   
#if defined ( __CC_ARM   )
/* ARM RVDS or Keil MDK */
__asm void FlashLoader_ASM(void)
{
   MOVS  R0,#0
   LDR   R1,[R0]     ; Get initial MSP value
   MOV   SP, R1
   LDR   R1,[R0, #4] ; Get initial PC value
   BX    R1
}

我想使用UartPuts函数打印出MSP值和PC值。

请您指导我如何打印出来?

2 个答案:

答案 0 :(得分:0)

一种方法(气体语法):

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

extern unsigned int GET32 ( unsigned int );
unsigned int x;
...
x = GET32(0x00000000);
...
x = GET32(0x00000004);

不需要asm的另一种方法:

#define ZERO (*((volatile unsigned int *)0x00000000))
#define FOUR (*((volatile unsigned int *)0x00000004))
...
unsigned int x;
...
x = ZERO;
...
x = FOUR;

如果您有stdint.h或等效版本,则可以使用uint32_t代替unsigned int。 (将导致gcc和clang / llvm的unsigned int)。

源自您的代码/语法

__asm uint32_t read_zero(void)
{
   MOVS  R0,#0
   LDR   R0,[R0]
   BX LR
}

__asm uint32_t read_four(void)
{
   MOVS  R0,#4
   LDR   R0,[R0]
   BX LR
}

答案 1 :(得分:0)

一个小警告。如果您尝试使用'C'从地址0x0进行读取,则很有可能会遇到编译时空指针陷阱,因为您的初始堆栈指针在C中定义为不是合法指针。

因此,取决于编译器(gcc 4.9.3之前的版本不会执行此操作),您可能会在汇编输出中看到完全意外的undef_opcode。没有从C中的地址0读取的“干净”方法,但是使用指针算术应该可以工作(除非您启用运行时空指针检查)。