在C89/C99兼容编译器上使用函数参数的地址是否安全/可移植?
例如,如果函数参数满足特定的大小和对齐要求,则32位ARM的AAPCS使用寄存器r0-r3进行参数传递.我假设使用通过寄存器传递的参数的地址会产生意外的结果,但我对我正在使用的ARM编译器运行了测试,如果代码尝试引用地址,它似乎将这些参数重定位到堆栈这些参数.虽然它在我的特定应用程序中似乎是安全的,但我想知道是否可以跨架构(使用符合ANSI/ISO的编译器)保证可以直接利用寄存器来传递函数参数.
标准是否定义了这种行为?
我使用各种微控制器架构/字大小为嵌入式系统开发固件,并尽可能地强调可移植性.我的问题是关于生成/应用安全和可移植的位掩码和标志,对于任何非通用代码,最坏的情况是什么.
位掩码
#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原始值中的所需位,它是否总是执行内码?
对于所有情况,假设:
对那些提到使用的人进行编辑stdint.h:我最近遇到了一个问题,我需要将一个串行协议处理程序移植到另一个微控制器系列,只发现RAM不是字节可寻址的.我们最终删除了uint8_t的所有用法,并进行了修改以使用16位可寻址内存.这让我想知道我是否可以使用本机C类型以不同方式实现它以避免以后的修改.我的问题来自这个问题.