数据宽度和存储容量的单位 数据在内存中的存放顺序 字节顺序 大端 小端 对齐 网络传输一般采用大端序 BigEndian ByteOrder
char x2; int x1; short x3; long long x4; 1,4,2,8 struct test { char x2; int x1; short x3; long long x4; } __attribute__((packed)); struct test1 { char x2; int x1; short x3; long long x4; }; struct test2 { char x2; int x1; short x3; long long x4; } __attribute__((aligned(4))); struct test3 { char x2; int x1; short x3; long long x4; } __attribute__((aligned(8))); struct test4 { char x2; int x1; short x3; long long x4; } __attribute__((aligned(16))); Linux short char 2字节对齐,其他4字节对齐 当cpu字长64位=8byte 1,4,2,8 #pragma pack() 1,4,2,8=15 1,4,2,8=0-0,4-7,8-9,16-23=24 1,4,2,8=0-0,4-7,8-9,12-19=20->24 1,4,2,8=0-0,4-7,8-9,12-19=20->24 1,4,2,8=0-0,4-7,8-9,12-19=20->32 # pragma pack(1) 1,4,2,8=15 1,4,2,8=15 1,4,2,8=15->16 1,4,2,8=15->16 1,4,2,8=15->16 # pragma pack(2) 1,4,2,8=15 1,4,2,8=0-0,2-5,6-7,8-15=16 1,4,2,8=0-0,2-5,6-7,8-15=16 1,4,2,8=0-0,2-5,6-7,8-15=16 1,4,2,8=0-0,2-5,6-7,8-15=16 # pragma pack(4) 1,4,2,8=15 1,4,2,8=0-0,4-7,8-9,12-19=20 1,4,2,8=0-0,4-7,8-9,12-19=20 1,4,2,8=0-0,4-7,8-9,12-19=20->24 1,4,2,8=0-0,4-7,8-9,12-19=20->32
#include <stdio.h> #pragma pack() struct test { char x2; int x1; short x3; long long x4; } __attribute__((packed)); struct test1 { char x2; int x1; short x3; long long x4; }; struct test2 { char x2; int x1; short x3; long long x4; } __attribute__((aligned(4))); struct test3 { char x2; int x1; short x3; long long x4; } __attribute__((aligned(8))); struct test4 { char x2; int x1; short x3; long long x4; } __attribute__((aligned(16))); void main() { printf("%lu \n", sizeof(struct test)); printf("%lu \n", sizeof(struct test1)); printf("%lu \n", sizeof(struct test2)); printf("%lu \n", sizeof(struct test3)); printf("%lu \n", sizeof(struct test4)); } 1 .file "alignment_pragma_pack.c" 2 .text 3 .section .rodata 4 .LC0: 5 .string "%lu \n" 6 .text 7 .globl main 8 .type main, @function 9 main: 10 .LFB0: 11 .cfi_startproc 12 endbr64 13 pushq %rbp 14 .cfi_def_cfa_offset 16 15 .cfi_offset 6, -16 16 movq %rsp, %rbp 17 .cfi_def_cfa_register 6 18 movl $15, %esi 19 leaq .LC0(%rip), %rax 20 movq %rax, %rdi 21 movl $0, %eax 22 call printf@PLT 23 movl $24, %esi 24 leaq .LC0(%rip), %rax 25 movq %rax, %rdi 26 movl $0, %eax 27 call printf@PLT 28 movl $24, %esi 29 leaq .LC0(%rip), %rax 30 movq %rax, %rdi 31 movl $0, %eax 32 call printf@PLT 33 movl $24, %esi 34 leaq .LC0(%rip), %rax 35 movq %rax, %rdi 36 movl $0, %eax 37 call printf@PLT 38 movl $32, %esi 39 leaq .LC0(%rip), %rax 40 movq %rax, %rdi 41 movl $0, %eax 42 call printf@PLT 43 nop 44 popq %rbp 45 .cfi_def_cfa 7, 8 46 ret 47 .cfi_endproc 48 .LFE0: 49 .size main, .-main 50 .ident "GCC: (Ubuntu 11.2.0-19ubuntu1) 11.2.0" 51 .section .note.GNU-stack,"",@progbits 52 .section .note.gnu.property,"a" 53 .align 8 54 .long 1f - 0f 55 .long 4f - 1f 56 .long 5 57 0: 58 .string "GNU" 59 1: 60 .align 8 61 .long 0xc0000002 62 .long 3f - 2f 63 2: 64 .long 0x3 65 3: 66 .align 8 67 4: 15 24 24 24 32 processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 142 model name : Intel(R) Core(TM) i3-10110U CPU @ 2.10GHz stepping : 12 cpu MHz : 2592.000 cache size : 4096 KB physical id : 0 siblings : 1 core id : 0 cpu cores : 1 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 22 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq monitor ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities bugs : spectre_v1 spectre_v2 spec_store_bypass swapgs itlb_multihit srbds mmio_stale_data retbleed bogomips : 5184.00 clflush size : 64 cache_alignment : 64 address sizes : 39 bits physical, 48 bits virtual power management:
对齐方式设定
f5 自然边界8,比4大,按4边界对齐,12是4倍数满足。
# pragma_pack(n)
自然边界比n大,按n字节对齐;反之按自然边界对齐。
减少插空: 结构体成员的顺序
计算机系统基础(一):程序的表示、转换与链接-模块八 第3讲 数据的对齐存放(1)-网易公开课 https://open.163.com/newview/movie/free?pid=WFVPGEQSL&mid=YFVPGFBSQ
结构数组变量最后可能需要插空,以使每个元素都边界对齐
Linux short char 2字节对齐,其他4字节对齐
对齐 alignment 可能需要插空 用空间换时间
传送单位 不是 1字节;传送按字长的整数倍数;存储按字节; 字长16位(历史)、32位、64位;
主存按照一个存储单位进行存取
检测系统的字节顺序
联合体
union的存放顺序是所有成员从低地址开始,利用该
特性可以测试CPU的大/小端方式。
指令地址 指令汇编形式
计算机系统基础(一):程序的表示、转换与链接-模块二 第7讲 数据存储时的字节排列-网易公开课 https://open.163.com/newview/movie/free?pid=WFVPGEQSL&mid=AFVPGF0JI
数的地址:存储单元中第一个字节的编号
例如:int i=-65535,存储时占4个字节, 存放在 100-103 4个存储单元;
100存储单元为该数的地址;
在100放第1个字节,则为小端
在100放第4个字节,则为大端
计算机系统基础(一):程序的表示、转换与链接-模块二 第6讲 数据宽度和存储容量的单位-网易公开课 https://open.163.com/newview/movie/free?pid=WFVPGEQSL&mid=PFVPGF0BI
存储器按照字节编址,一个字节为一个存储单位,一个数据,可能占多个字节,怎么排序呢?
LSB 最低有效字节 ,在低位则小端
MSB 高