[英]How do bit-fields work in C?
我剛剛了解了C語言中的位域,並且對編譯器如何實現此功能感到好奇。 就我對C編譯器的了解而言,單個位不能單獨訪問。
通過讀取周圍的存儲器可尋址單元(字節或字),屏蔽和移位來實現位字段。
更精確地,讀取位字段被實現為讀取移位掩碼,並且對位字段的寫入被實現為寫入或寫入的讀取掩碼移位值。
這是相當昂貴的,但是如果您打算緊湊地存儲數據並願意為按位操作付出代價,那么位字段在源代碼級別為您可以手工編寫的相同操作提供了更清晰,更輕松的語法。 您所失去的是對布局的控制(標准未指定如何從包含的單詞分配位域,這在編譯器之間的差異遠大於按位運算的含義)。
每當您對C編譯器對給定結構的功能有疑問時,都可以隨時閱讀匯編代碼:
struct s {
unsigned int a:3;
unsigned int b:3;
} s;
void f(void)
{
s.b = 5;
}
int g(void)
{
return s.a;
}
這是由gcc -O -S
編譯為:
_f: ## @f
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
movq _s@GOTPCREL(%rip), %rax
movb (%rax), %cl ; read
andb $-57, %cl ; mask
orb $40, %cl ; since the value to write was a constant, 5, the compiler has pre-shifted it by 3, giving 40
movb %cl, (%rax) ; write
popq %rbp
retq
.cfi_endproc
.globl _g
.align 4, 0x90
_g: ## @g
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp7:
.cfi_def_cfa_offset 16
Ltmp8:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp9:
.cfi_def_cfa_register %rbp
movq _s@GOTPCREL(%rip), %rax
movzbl (%rax), %eax
andl $7, %eax
popq %rbp
retq
.cfi_endproc
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.