It uses eax instead of rax, because you're not using 64-bit numbers. There is no reason to. The compilers optimize for small binaries, and using the 64-bit register get encoded to longer instructions, I believe another byte or so, possibly more in some cases. So, if you are using 32 bit numbers, encoding a 64 bit register increasing the binary size for no good reason, the compiler is smart enough to realize you are using 32 bit numbers. When the value gets copied to a 64 bit register, it can just zero extend for free, basically.
Instead of moving value between registers directly, ``` move eax, edi ``` Why the compiler first moves the value to memory then copy to the register like below? ``` mov dword ptr [rbp-4], edi mov eax, dword ptr [rbp-4] ```
He didn't answer the question at 24:30, why use `lea` instead of `mov`. The question was "why don't we take off the dereference operator (square brackets) to and use actual value stored in the register, substracting 8 on the fly: `mov rdi, rsp - 8` and I still can't find the answer other than "that's just how it is".
You cannot move and subtract in one instruction, other than using LEA, which reuses the effective address calculation circuitry for that operation. Because that's what it historically is: there's a specialised ALU used for calculating addresses, and LEA is simply an instruction (on multiple platforms) that doesn't use that calculated address for anything else other than its numeric value. This also means that LEA shares it's calculating limitations with instructions that actually do access memory, so it make sense to use the bracket syntax, you just need to remember than LEA is the exception that will never do a memory access. So, to recap: 1) brackets everywhere we're calculating the effective address, for uniformity 2) all instructions that operate on data (MOV, ADD, etc.), interpret brackets as memory access 3) but we do not do a memory access, we're just loading the effective address into a register, so we need to have a special name for this, like Load Effective Address - LEA
Right off the bat I took issue with the register having the value two being copied as a literal 2 instead of the expected 1 . This appears as 00000002 instead of 00000001 . A register containing 4 should be 00000010 and not 00000004 . Maybe I'm just a noob nit picker but ? If the register can also contain instructions as binary things could get pretty screwed up ! Obviously I'm a beginner , and yet wtf ?---I get it . It's just an abbreviation for a 64 bit binary .
He mentioned that it was in hex, maybe you are not familiar with it? It's primarily used because its shorter but also because 1 hex digit maps directly to 4 binary digits (bits), i.e. C always maps to 1010. Also, you seem a bit confused about binary? 2 is 10 in binary not 1. 4 is 100. Another thing is that including leading zeroes in binary is not very practical because a register in modern computers is 64 bits long. So 2 in binary is 0000000000000000000000000000000000000000000000000000000000000010 which is somewhat inconvenient to use.
off topic: as a C++ and computer science teacher/tutor I really dislike tutorial/test programs that have problems like the presenter showed in the slide at the beginning of the presentation. we teach students that globally scoped entities are something to be suspicious of, that they should use descriptive variable names, and that the code they write should directly express the solution to the problem they're solving - and then support material like what the presenter showed throws not only C++ standards out the window but also general good programming practices, then I get students who think their code isn't clever if it's not code golf, not to mention how those things slows adoption of C++ core guideline standards as students then think the core guidelines are the awkward and odd style... ahem, any way carry on lol
Hi Georg, the presenter here. I very much agree with your coding guidelines, and appreciate that you are teaching those. Which slide in particular are you referring to?
One of the best introductions to x86 64 Assembly.
Best comprehensive intro I've found so far for assembly for C++ guys. Kudos to the presenter !
that was very clear and informative, thank you!
You're very welcome!
Very nice and informative talk, thank you!
Glad it was helpful!
Thanks Anders, learnt a lot from this talk :)
It uses eax instead of rax, because you're not using 64-bit numbers. There is no reason to. The compilers optimize for small binaries, and using the 64-bit register get encoded to longer instructions, I believe another byte or so, possibly more in some cases. So, if you are using 32 bit numbers, encoding a 64 bit register increasing the binary size for no good reason, the compiler is smart enough to realize you are using 32 bit numbers. When the value gets copied to a 64 bit register, it can just zero extend for free, basically.
Really nice talk!
Glad you think so!
Thank you! :)
Great talk!
Nice explanation.
Glad it was helpful!
Instead of moving value between registers directly,
```
move eax, edi
```
Why the compiler first moves the value to memory then copy to the register like below?
```
mov dword ptr [rbp-4], edi
mov eax, dword ptr [rbp-4]
```
lovely !
Exellent
I like to code in assembly, but i never use a compiler, so i do not need to use the calling convention.
I admit this is insane - they even have risc-v )
He didn't answer the question at 24:30, why use `lea` instead of `mov`. The question was "why don't we take off the dereference operator (square brackets) to and use actual value stored in the register, substracting 8 on the fly: `mov rdi, rsp - 8` and I still can't find the answer other than "that's just how it is".
You cannot move and subtract in one instruction, other than using LEA, which reuses the effective address calculation circuitry for that operation. Because that's what it historically is: there's a specialised ALU used for calculating addresses, and LEA is simply an instruction (on multiple platforms) that doesn't use that calculated address for anything else other than its numeric value. This also means that LEA shares it's calculating limitations with instructions that actually do access memory, so it make sense to use the bracket syntax, you just need to remember than LEA is the exception that will never do a memory access.
So, to recap: 1) brackets everywhere we're calculating the effective address, for uniformity 2) all instructions that operate on data (MOV, ADD, etc.), interpret brackets as memory access 3) but we do not do a memory access, we're just loading the effective address into a register, so we need to have a special name for this, like Load Effective Address - LEA
@@vytah thanks for this !
Right off the bat I took issue with the register having the value two being copied as a literal 2 instead of the expected 1 . This appears as 00000002 instead of 00000001 . A register containing 4 should be 00000010 and not 00000004 . Maybe I'm just a noob nit picker but ? If the register can also contain instructions as binary things could get pretty screwed up ! Obviously I'm a beginner , and yet wtf ?---I get it . It's just an abbreviation for a 64 bit binary .
He mentioned that it was in hex, maybe you are not familiar with it? It's primarily used because its shorter but also because 1 hex digit maps directly to 4 binary digits (bits), i.e. C always maps to 1010. Also, you seem a bit confused about binary? 2 is 10 in binary not 1. 4 is 100.
Another thing is that including leading zeroes in binary is not very practical because a register in modern computers is 64 bits long. So 2 in binary is
0000000000000000000000000000000000000000000000000000000000000010
which is somewhat inconvenient to use.
Values are in hexadecimal, not binary 🙂
As he said, it's hex, not binary.
Just for fun! Your name sounds like an Egyptian Pharoah.
Haha, then I know what to do in case of a career change!
off topic: as a C++ and computer science teacher/tutor I really dislike tutorial/test programs that have problems like the presenter showed in the slide at the beginning of the presentation. we teach students that globally scoped entities are something to be suspicious of, that they should use descriptive variable names, and that the code they write should directly express the solution to the problem they're solving - and then support material like what the presenter showed throws not only C++ standards out the window but also general good programming practices, then I get students who think their code isn't clever if it's not code golf, not to mention how those things slows adoption of C++ core guideline standards as students then think the core guidelines are the awkward and odd style... ahem, any way carry on lol
Hi Georg, the presenter here. I very much agree with your coding guidelines, and appreciate that you are teaching those. Which slide in particular are you referring to?