我发现这个宏函数允许我在C中创建二进制文字.
宏功能:
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) + B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) \
(((unsigned long)B8(dmsb)<<24) \
+ ((unsigned long)B8(db2)<<16) \
+ ((unsigned long)B8(db3)<<8) \
+ B8(dlsb))
Run Code Online (Sandbox Code Playgroud)
它运行正常,但是当我尝试在宏函数中使用int变量时,它会给我一个后缀错误.
int i=10001000;
B8(i); //invalid suffix 'xiLU' on integer constant
B8(10001000); //no error
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?(还要注意我在TI TM4C LaunchPad上用C编码,如果这很重要的话)
我想知道为什么在ARM组件中注册后附加'm'.例如:
msr cpsr, r0m
^
Run Code Online (Sandbox Code Playgroud)
在手动中,msr命令定义如下:
MSR{cond} psr_fields, Rm
^
Run Code Online (Sandbox Code Playgroud) 假设您有一个指向函数的指针,该函数的源代码是您没有的,而且是"不可信的",因为它可能会读取/写入不允许的内存区域.
在执行每个汇编指令之前,您需要验证它是否不访问不允许的内存区域.
操作系统(几乎)是裸机,即自定义RTOS(因此没有Linux或QNX).
这适用于不仅需要在开发期间而且在正常运行时期间启用的功能.
理想情况下,它运行如下:
void (*fptr)(int);
fptr = &someFunction; // untrusted, don't have source
// enable interrupts for each assembly instruction
_EN_INT();
// call the function
fptr();
// everytime the PC increments, some other code runs which verifies that if any load/stores are executed, it doesn't access some disallowed memory range
// disable interrupts for each assembly instruction
_DIS_INT();
Run Code Online (Sandbox Code Playgroud)
题
是否可以在每个汇编指令后调用该函数并暂停执行?
代码:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
typedef unsigned int uint32_t;
float average(int n_values, ... )
{
va_list var_arg;
int count;
float sum = 0;
va_start(var_arg, n_values);
for (count = 0; count < n_values; count += 1) {
sum += va_arg(var_arg, signed long long int);
}
va_end(var_arg);
return sum / n_values;
}
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
printf("hello world!\n");
uint32_t t1 = 1;
uint32_t t2 = 4;
uint32_t t3 = 4;
printf("result:%f\n", average(3, t1, t2, t3));
return …Run Code Online (Sandbox Code Playgroud) 我试图简单地将一个double转换为C中的字符串
?char printable[9];
snprintf(printable, 9, "%f", 30.356145);
Run Code Online (Sandbox Code Playgroud)
应将printtable设置为"30.35614".当我在在线c编译器上运行此代码时,它正确输出.当我在我的微控制器上输出它时,打印等于这个废话:
"\000\033\000\000\001\000\000\000\024"
Run Code Online (Sandbox Code Playgroud)
我试图在我的代码执行算术运算时使用CPSR标志,而不是使用一系列if语句来检查溢出,进位等,以便拥有更小,更快的代码.一个简单的例子是这个加法操作:
int16_t a = 0x5000;
int16_t b = 0x4000;
int16_t result = a+b;
uint32_t flags = getFlags();
Run Code Online (Sandbox Code Playgroud)
代码需要在各种平台上运行,因此getFlags()是允许包含特定于体系结构的程序集的代码的唯一部分.
inline uint32_t getFlags() {
uint32_t flags = 0;
asm (“mrs %0, cpsr”
: “=r” (flags)
:
: );
return flags;
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器没有任何方式知道此示例中的加法操作应该设置标志,因此它生成类似于以下的指令:
ldrsh r3, [r0]
ldrsh r4, [r1]
add r3, r3, r4
strh r3, [r2]
mrs r3, cpsr
Run Code Online (Sandbox Code Playgroud)
为了使CPSR包含任何有用的东西,我需要编译器使用adds而不是add(s suffix = update CPSR).我可以在我的C代码或可能的编译器选项中更改它会导致它选择标志更新指令吗?我可以使用GCC或Clang.
是否有内置的gccmemcopy功能,专门针对ARM Cortex M4的架构进行了优化?
我搜索了ARM Cortex-A53处理器,发现它使用了静态的有序管道,在该指令中依次执行,执行和提交。我不明白为什么这样的现代处理器会使用有序执行,因为无序执行的速度更快,因为它可以更好地处理控制和数据危害。
在AArch64程序集中,以下行
stp x25, x30, [sp,#48]
Run Code Online (Sandbox Code Playgroud)
将x25存储在sp + 48,将x30存储在sp + 56,对吗?