Octocontrabass wrote:
It doesn't. How could it? The memory doesn't remember how you wrote the values, it only remembers the values.
(Okay, technically it could impact alignment, since a packed struct has byte-alignment and an array of 64-bit integers has 64-bit alignment, but that only affects speed.)
Bear with me. My question is regarding how the endian-ness might affect how the segment descriptor is read.
Take for example two representaions that occupy 2 bytes of memory. A struct that looks like:
Code: Select all
struct [[gnu::packed]] Packed {
std::uint8_t x;
std::uint8_t y : 4;
std::uint8_t z : 4;
};
Packed p = { .x = 0x12, .y = 0x3, .z = 0x4 };
and an unsigned 2 byte value.
These are laid out in memory differently.
Here's the generated assembly
Code: Select all
0x555555555129 <main()> endbr64
0x55555555512d <main()+4> push rbp
0x55555555512e <main()+5> mov rbp,rsp
0x555555555131 <main()+8> movzx eax,WORD PTR [rip+0xecc] # 0x555555556004
0x555555555138 <main()+15> mov WORD PTR [rbp-0x2],ax
0x55555555513c <main()+19> mov WORD PTR [rbp-0x4],0x1234
0x555555555142 <main()+25> mov eax,0x0
0x555555555147 <main()+30> pop rbp
0x555555555148 <main()+31> ret
Here are the initializations.
Code: Select all
0x555555555131 <main()+8> movzx eax,WORD PTR [rip+0xecc] # 0x555555556004
0x555555555138 <main()+15> mov WORD PTR [rbp-0x2],ax
0x55555555513c <main()+19> mov WORD PTR [rbp-0x4],0x1234
You could see that these values differ in byte arrangement because of endian-ness. Demonstrated in gdb, here is the struct:
Code: Select all
# This is the struct
0x555555556004: 0x4312
(gdb) x/1xh $rbp - 2
0x7fffffffdeae: 0x4312
(gdb) x/2xb $rbp - 2
0x7fffffffdeae: 0x12 0x43
And here is the `std::uint16_t`
Code: Select all
(gdb) x/1xh $rbp - 4
0x7fffffffdeac: 0x1234
(gdb) x/2xb $rbp - 4
0x7fffffffdeac: 0x34 0x12
The key difference being these two lines:
Code: Select all
(gdb) x/2xb $rbp - 2
0x7fffffffdeae: 0x12 0x43
and
Code: Select all
(gdb) x/2xb $rbp - 4
0x7fffffffdeac: 0x34 0x12
The struct and `std::uint16_t` are laid out different.
But back to my original question, the segment limit (bits 0 - 15) occupy two least significant bytes and reads from memory (from my understanding) are from lowest to highest. So, should I have put my struct member std::uint16_t segment_limit_low to account for this?