C语言如何获取asm变量值?
How do I get the asm variable value in C language?
现在我正在尝试了解 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 值。
你能指导我如何打印出来吗?
一种方式(gas 语法):
.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)。
源自您的code/syntax
__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
}
一个小警告。如果您尝试使用 'C' 从地址 0x0 读取,您很可能 运行 进入编译时空指针陷阱,因为您的初始堆栈指针指针在 C 中定义为不是合法指针。
因此,根据编译器的不同(gcc 4.9.3 之前的版本不会这样做),您可能会在汇编输出中看到完全出乎意料的 undef_opcode
。在 C 中没有 'clean' 从地址 0 读取的方法,但使用指针算术应该可行(除非你启用 运行time 空指针检查)。
现在我正在尝试了解 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 值。
你能指导我如何打印出来吗?
一种方式(gas 语法):
.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)。
源自您的code/syntax
__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
}
一个小警告。如果您尝试使用 'C' 从地址 0x0 读取,您很可能 运行 进入编译时空指针陷阱,因为您的初始堆栈指针指针在 C 中定义为不是合法指针。
因此,根据编译器的不同(gcc 4.9.3 之前的版本不会这样做),您可能会在汇编输出中看到完全出乎意料的 undef_opcode
。在 C 中没有 'clean' 从地址 0 读取的方法,但使用指针算术应该可行(除非你启用 运行time 空指针检查)。