小编ohi*_*ick的帖子

功能参数的C地址?

在C89/C99兼容编译器上使用函数参数的地址是否安全/可移植?

例如,如果函数参数满足特定的大小和对齐要求,则32位ARM的AAPCS使用寄存器r0-r3进行参数传递.我假设使用通过寄存器传递的参数的地址会产生意外的结果,但我对我正在使用的ARM编译器运行了测试,如果代码尝试引用地址,它似乎将这些参数重定位到堆栈这些参数.虽然它在我的特定应用程序中似乎是安全的,但我想知道是否可以跨架构(使用符合ANSI/ISO的编译器)保证可以直接利用寄存器来传递函数参数.

标准是否定义了这种行为?

c arm

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

在C中应用便携式位掩码和标志

我使用各种微控制器架构/字大小为嵌入式系统开发固件,并尽可能地强调可移植性.我的问题是关于生成/应用安全和可移植的位掩码和标志,对于任何非通用代码,最坏的情况是什么.

位掩码

#define MASK_8_V1(x) ((x) & 0xFF)
#define MASK_8_V2(x) ((x) & 0x00FF)

a = MASK_8_V1(b)
a = MASK_8_V2(b)
Run Code Online (Sandbox Code Playgroud)

这些总是保证获得宽度的值,除了b中的低8之外,所有位都为零.两个版本之间是否有任何区别,因为如果有必要,它们应该签名延长?

#define GEN_FLAG_16(x) ((0xFFFF) & ((unsigned) 1 << (x)))
#define GEN_FLAG_32(x) ((0xFFFFFFFF) & ((unsigned long) 1 << (x)))
Run Code Online (Sandbox Code Playgroud)

如果我需要一个通用的宏来生成标志常量,这总是会导致列出的宽度的标志常量?

#define CHECK_FLAG_16(x, y) ((x) & GEN_FLAG_16(y))
#define CHECK_FLAG_32(x, y) ((x) & GEN_FLAG_32(y))

if(CHECK_FLAG_16(a, b))
{
    // Do something.
}
Run Code Online (Sandbox Code Playgroud)

结合以前的场景,如果设置了b原始值中的所需位,它是否总是执行内码?

对于所有情况,假设:

  • 符合C90或C99标准的编译器
  • a和b可以是本机C类型的任意组合,有符号或无符号
  • x始终求值为正整数类型
  • 任意原生单词大小

对那些提到使用的人进行编辑stdint.h:我最近遇到了一个问题,我需要将一个串行协议处理程序移植到另一个微控制器系列,只发现RAM不是字节可寻址的.我们最终删除了uint8_t的所有用法,并进行了修改以使用16位可寻址内存.这让我想知道我是否可以使用本机C类型以不同方式实现它以避免以后的修改.我的问题来自这个问题.

c embedded microcontroller

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

标签 统计

c ×2

arm ×1

embedded ×1

microcontroller ×1