flat assembler
Message board for the users of flat assembler.
Index
> Main > Assembly Unions |
Author |
|
Furs 13 Sep 2017, 14:44
They don't share the same value in C either. They're wrapped in a struct inside the union. The struct is "one element" and contains four elements itself (but the union sees it as one element).
The struct is shared with the 'addr' member though. EDIT: The final result 100007f is because it's little endian -- it stores the least significant byte first in memory. (this actually makes far more sense since we read left to right -- our numbers, by default, are written the wrong way around; we just got used to it, but it's not logical at all, since we write words left-to-right but read numbers right-to-left since you can't even pronounce how high a number is without seeing how deep it goes first) |
|||
13 Sep 2017, 14:44 |
|
The_Unknown_Member 13 Sep 2017, 16:15
Furs wrote: They don't share the same value in C either. They're wrapped in a struct inside the union. The struct is "one element" and contains four elements itself (but the union sees it as one element). Thanks. But why it's little endian ? Shouldn't it be little endian only in the memory? Look at this: Code: format PE console use32 ; x86_32 entry start include 'win32a.inc' ; This is the data section: ; ======================================================= section '.data' data readable writeable num dd 1 dup(0) ; ======================================================= section '.text' code readable executable start: ; Your program begins here mov dword [num], 18693h mov eax, [num] ; Output -> 18693 ; Exit the process: push 0 call [ExitProcess] Here in this code I get the result in big endian's format. Hexadecimal is read from right to left just like the binary right ? The most significant bit is the leftmost bit and the least significant bit is the rightmost bit ? |
|||
13 Sep 2017, 16:15 |
|
Furs 13 Sep 2017, 16:28
I'm not sure I understand your confusion but, let me try explain.
The first byte, which is a, is the least significant byte. Your value is "100007f". This value's least significant byte is 7F, which is correct since a is 7F. It makes sense that a lower memory address contains a lesser significant byte, right? In a decimal number, say 1234, the least significant digit is 4 (rightmost). Adding 1 to it gives you 1235 -- least significant carries to the left (i.e. right-to-left, backwards, due to human number notation) Again, in human notation, we read the number from right to left subconsciously. They're just written backwards compared to words. That's why I think little endian is just "logical". Lower memory -> lower byte. I guarantee if you start to consciously read numbers from right to left, all confusion will be gone. (after all, we can't process a number like "1000000" without first seeing all of its digits, we don't know how big '1' is before we see the least significant digit, so subconsciously we need to read it from right to left) If our numbers were written left-to-right, we wouldn't have this problem. Then when we see a digit we don't have to rewind for its meaning later. We know the first one is always the least significant and know exactly of its impact without knowing the number's "length". Big endian is just stupid like that. Last edited by Furs on 13 Sep 2017, 16:32; edited 1 time in total |
|||
13 Sep 2017, 16:28 |
|
revolution 13 Sep 2017, 16:29
The data stored in memory is little endian. The first byte is 0x93, the next is 0x86, etc.
0x18693 is stored as four bytes: 0x93, 0x86, 0x01, 0x00. And is read back the same way, so 0x93 is put into the lowest byte of eax. Edit: Cross post with Furs. |
|||
13 Sep 2017, 16:29 |
|
The_Unknown_Member 13 Sep 2017, 20:24
revolution wrote: The data stored in memory is little endian. The first byte is 0x93, the next is 0x86, etc. But look at this example: Code: section '.bss' readable writeable num dd 1 dup (?) section '.text' code readable executable start: ; Your program begins here mov [num], 1034fh mov eax, [num] ; Output -> 1034f ; Exit the process: push 0 call [ExitProcess] Here i am moving 1034f to the memory and the output is still 1034f it's not in reversed order |
|||
13 Sep 2017, 20:24 |
|
revolution 13 Sep 2017, 20:28
The assembler converts and stores your number in little endian format. You see it in the source code as big endian, but if you disassemble the code and look at the hex output it is little endian. So it is only an optical illusion tricking you.
|
|||
13 Sep 2017, 20:28 |
|
The_Unknown_Member 13 Sep 2017, 21:09
revolution wrote: The assembler converts and stores your number in little endian format. You see it in the source code as big endian, but if you disassemble the code and look at the hex output it is little endian. So it is only an optical illusion tricking you. So when I write code I must think in the Big Endian way and when I read the code from hex editor I must think in the Little Endian way ? |
|||
13 Sep 2017, 21:09 |
|
revolution 13 Sep 2017, 21:11
The_Unknown_Member wrote: So when I write code I must think in Big Endian way and when I read the code from hex editor I must think in Little Endian way ? |
|||
13 Sep 2017, 21:11 |
|
The_Unknown_Member 13 Sep 2017, 21:49
revolution wrote:
Okay I understood. Thanks very much! |
|||
13 Sep 2017, 21:49 |
|
Furs 13 Sep 2017, 21:53
@The_Unknown_Member: Here's an example of two cases:
Code: db 1, 2, 3, 4 ; 4 bytes in this order dd 0x04030201 ; assembles to the exact same thing, but because we store the "dword" at once, in source code it's "big endian" so it's reversed Or, alternatively, imagine the memory backwards: it starts from right and goes to left. (i.e. byte 0 is to the right of byte 1, though most Hex Editors don't have such option; but then you have to think that way when using "db" or the like too). @revolution: I loved your use of "optical illusion" |
|||
13 Sep 2017, 21:53 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.