长城h1报价及图片-东风悦达 起亚k4
2023年11月24日发(作者:雷克萨斯suv)
宏函数返回值(CC++)
1 背景
最近开发新模块的驱动,看了下?佬提交的代码(封装给我?),每个寄存器读写通过宏函数封装实现的API。另外,我们的Linux内核中
很多的函数也是通过宏函数定义的。按照其格式修改下,?致如下,:
/**/
寄存器定义
typedef struct{
unsigned int rx_en : 1 ;
unsigned int a : 1 ;
unsigned int b : 2 ;
unsigned int c : 1 ;
unsigned int d : 1 ;
unsigned int e : 3 ;
unsigned int f : 7 ;
unsigned int g : 14 ;
unsigned int h : 2 ;
} __attribute__ ((packed)) Reg_ModuleRxCfg;
/*
*SET_MODULE_RX_ENABLE(_en) RX
使能宏函数写接?
*GET_MODULE_RX_ENABLE() RX
使能宏函数读接?
*MODULE_REG_READMODULE_REG_WRITE
、寄存器读写
*/
#define SET_MODULE_RX_ENABLE(_en)
do {Reg_ModuleRxCfg __c = {0};
MODULE_REG_READ(MODULE_RX_CFG, (unsigned int *)&__c);
__c.rx_en = !!_en;
MODULE_REG_WRITE(MODULE_RX_CFG, *((unsigned int *)&__c));
}while(0)
#define GET_MODULE_RX_ENABLE()
({ Reg_ModuleRxCfg __c1 = {0}; unsigned int __c;
MODULE_REG_READ(MODULE_RX_CFG, (unsigned int *)&__c);
memcpy((void*)&__c1, (void*)&__c, sizeof(unsigned int));
__c1.rx_en;
})
/*
*
接?使?
*/
SET_MODULE_RX_ENABLE(1);
unsigned char RxEnable = 0;
RxEnable = GET_MODULE_RX_ENABLE();
接?使?处,写寄存器还好理解,但是读就不好理解了,宏函数返回值是什么
2宏函数返回值
接下来就来?看究竟。
直接仿照写段代码,跑?下:
#include
#define REGREAD(_DAYOFWEEK_)
({
char* str;
switch (_DAYOFWEEK_){
case 1:
case 2:
case 3:
case 4:
case 5:
str = \"?伙?,好好上班!\";
break;
case 6:
case 7:
str = \"?伙?,来加个班呀!\";
break;
default:
str = \"?伙?,今年过年别回家了,加个班吧!\";
}
(str);
})
int main() {
int i;
char* str;
for(i = 0; i <= 7; i++){
str = REGREAD(i);
printf(\"%sn\", str);
}
return 0;
}
跑?下:
从输出可以看出:
宏函数的返回值,即宏函数中最后?个表达式的值;宏函数的返回值的类型,是最后?个表达式的类型。
3 汇编查看
gcc -S macro_return.c -o macro_return.s
.file \"macro_return.c\"
.text
.section .rodata
.LC0:
.string \"3452645275345245275344275357274201\"
.align 8
.LC1:
.string \"345263524534523452212\"
.align 8
.LC2:
.string \"345267323545256266
344272206,3452345221\"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl $0, -4(%rbp)
jmp .L2
.L7:
cmpl $0, -4(%rbp)
jle .L3
cmpl $5, -4(%rbp)
jle .L4
cmpl $7, -4(%rbp)
jg .L3
jmp .L9
.L4:
movq $.LC0, -16(%rbp)
jmp .L6
.L9:
movq $.LC1, -16(%rbp)
jmp .L6
.L3:
movq $.LC2, -16(%rbp)
.L6:
movq -16(%rbp), %rax
movq %rax, -24(%rbp)
movq -24(%rbp), %rax
movq %rax, %rdi
call puts
addl $1, -4(%rbp)
.L2:
cmpl $7, -4(%rbp)
jle .L7 /*jle:*/
条件转移指令。?于或等于,或者不?于则转移
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident \"GCC: (GNU) 8.3.1 20190507 (Red Hat 8.3.1-4)\"
.section .note.GNU-stack,\"\",@progbits
有点乱,简单分析下:
1、从函数开始,进?再到,在中进?
main.L2.L7.L7for循环和判断
2、是switch中对应不同case的标签,可以看出中的字符串放到了寄存器
.L4、.L9、.L3.LC0:、.LC1:、.LC2:-16(%rbp)
3、最后在中进?处理,并调?了puts函数,将字符串输出。
.L6:
从汇编也可以看出,输出的是最后?个表达式的值。
卡宴coupe价格-上汽maxusrv80房车
更多推荐
开c260l的都是穷人
发布评论