Try   HackMD

你所不知道的 C 語言:記憶體管理、對齊及硬體特性

Source

Data alignment

Endianness

  • Big Endian
    最高位元放在word的起始位址
  • Little Endian
    最低位元放到word的起始位址

Get unaligned

考慮以下 unaligned_get32 函式的實作:

  1. 硬體架構為 32-bits
  2. 位元組順序 Little endian
#include <stdint.h>
#include <stddef.h>
uint8_t unaligned_get8(void *src) {
    uintptr_t csrc = (uintptr_t) src;
    uint32_t v = *(uint32_t *) (csrc & 0xfffffffc);
    v = (v >> (((uint32_t) csrc & 0x3) * 8)) & 0x000000ff;
    return v;
}
uint32_t unaligned_get32(void *src) {
    uint32_t d = 0;
    uintptr_t csrc = (uintptr_t) src;
    for (int n = 0; n < 4; n++) {
        uint32_t v = unaligned_get8((void *) csrc);
        v = v << (n * 8);
        d = d | v;
        csrc++;
    }
    return d;
}
  • uint32_t unaligned_get32(void *src)
  1. uintptr_t csrc = (uintptr_t) src

v & 0x000000ff = 0xef

  1. csrc++

v & 0x000000ff = 0xbe

  1. csrc++

v & 0x000000ff = 0xad

  1. csrc++

v & 0x000000ff = 0xde

  • d = 0xdeadbeef
#include <stdio.h>
#include <stdint.h>

int main(void) {
    uint32_t a = 0xdeadbeef;
    printf("a = %x\n", a);
    printf("&a = %p\n", &a);
    a = a >> 8;
    uint8_t *b = &a;
    printf("\nb = %p\n", b);
    printf("*(b) = %x\n", *(b));
    printf("*(b+1) = %x\n", *(b+1));
    printf("*(b+2) = %x\n", *(b+2));
    return 0;
}
$ ./main
a = deadbeef
&a = 0x7ffec2dc29d4

b = 0x7ffec2dc29d4
*(b) = be
*(b+1) = ad
*(b+2) = de