Memory alignment

Pages: 12
Aligned to 32 bits:
DEADBEE0 80
DEADBEE1 00
DEADBEE2 10
DEADBEE3 57

DEADBEE4 F5
DEADBEE5 A0
DEADBEE6 ??
DEADBEE7 ??

Aligned to 16 bits:
DEADBEE0 ??
DEADBEE1 ??
DEADBEE2 80
DEADBEE3 00

DEADBEE4 10
DEADBEE5 57
DEADBEE6 F5
DEADBEE7 A0

In the first case, the CPU can read the first 32 bits of the MAC address in one operation, but in the second case the first 32 bits cross a 32-bit boundary, so the CPU needs to perform two reads, and then it make need yet another read to get the last 16 bits. In such an architecture, it may be quicker to compare the addresses in 16-bit chunks at a time, even it takes more bitwise operations.


ah ok, that kind of makes sense now :), going back to the 32 bit example:
the compiler pads the 16 bits ( end of mac address ) with an extra 16 bits so it can be 32 bit aligned,correct?

also the second final bytes will always be aligned because at most it will only take one read to get the contents of them 2 bytes, correct?

also in the 16 bits example:
the first 2 bytes are padded followed by the first 2 bytes of the mac addr , but it could just as easily be the following right?:

Aligned to 16 bits:
DEADBEE0 80
DEADBEE1 00
DEADBEE2 10
DEADBEE3 57

DEADBEE4 F5
DEADBEE5 A0
DEADBEE6 ??
DEADBEE7 ??

: "alignment" means that the address of an object is a multiple of an integer, usually a power of 2. In the case of the above function, "aligned to 16 bits" means that this is true: (uintptr_t)addr1 % 2 == 0. Nothing more.


still not too sure of this though, in this case ( aligned to 16 bits ) ( (uintptr_t)addr1 % 2 == 0 ) == ( (uintptr_16)addr1 % 2 == 0) right?

how would (uintptr_16)addr1 % 2 == 0 relate to the addressing scheme?

Last edited on
the compiler pads the 16 bits ( end of mac address ) with an extra 16 bits so it can be 32 bit aligned,correct?
The function receives a byte pointer. What's at addr1 + 6 is completely unknown. It could be padding, it could be another MAC, it could be something else entirely.

but it could just as easily be the following right?
If something is n*k-aligned then it's also n-aligned and k-aligned, as implied by the definition I gave in my previous post:
"alignment" means that the address of an object is a multiple of an integer


still not too sure of this though, in this case ( aligned to 16 bits ) ( (uintptr_t)addr1 % 2 == 0 ) == ( (uintptr_16)addr1 % 2 == 0) right?

how would (uintptr_16)addr1 % 2 == 0 relate to the addressing scheme?
uintptr_16 is not a type, so I don't know what you're trying to say.

My statement was really simple: If you take the address of the object and convert it to an integer value, if that value is divisible by 2 then the object is aligned to 16 bits. There's no simpler way to put.
the compiler pads the 16 bits ( end of mac address ) with an extra 16 bits so it can be 32 bit aligned,correct?
The function receives a byte pointer. What's at addr1 + 6 is completely unknown. It could be padding, it could be another MAC, it could be something else entirely.


that's true but if it's 32 bit aligned, it now only has 4 bytes(the ?? bytes) left to meet that requirement right? so it could be padding, but it could be a short ( 2 bytes ) or 2(chars) but it couldn't be for example another integer or 32 bit value as this would cause misalignment right?

Aligned to 32 bits:
DEADBEE0 80
DEADBEE1 00
DEADBEE2 10
DEADBEE3 57

DEADBEE4 F5
DEADBEE5 A0
DEADBEE6 ??
DEADBEE7 ??




(uintptr_t)addr1 % 2 == 0


I don't understand what type (uintptr_t) is, I've seen the formula: address % N == 0 before but not sure how this formula works in relation to alignment.
Last edited on
so it could be padding, but it could be a short ( 2 bytes ) or 2(chars) but it couldn't be for example another integer or 32 bit value
Yes, it could be. Run this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <cstddef>
#include <cstdint>

bool is_16bit_aligned(void *p){
	return (uintptr_t)p % 2 == 0
}

bool is_32bit_aligned(void *p){
	return (uintptr_t)p % 4 == 0
}

#pragma pack(push)
#pragma pack(1)
struct A{
	std::uint8_t mac[6];
	std::uint32_t foo;
}
#pragma pack(pop)

int main(){
	std::uint8_t raw_memory[256];
	auto base = raw_memory;
	while (!is_32bit_aligned(base))
		base++;
	//base is now definitely aligned to a 32-bit boundary.
	auto a = (A *)base;
	
	std::cout << is_16bit_aligned(a->mac) << std::end;
	std::cout << is_16bit_aligned(&a->foo) << std::end;
	return 0;
}

Remember: alignment is a property of addresses.

I don't understand what type (uintptr_t) is
uintptr_t and intptr_t are integers large enough to hold void * losslessly.

I've seen the formula address % N == 0 before but not sure how this formula works in relation to alignment.
"alignment" means that the address of an object is a multiple of an integer
Registered users can post here. Sign in or register to post.
Pages: 12