First, let me point out that using GCC to
learn inline assembly is a significant disadvantage.
This is because GCC introduces a layer to be learned on top of the underlying subject. The underlying subject, for a Windows target, is x86_64 assembler (and/or possibly 32 bit x86 if you're writing such targets).
The layer GCC puts on top of that is called the AT&T syntax (which makes every Intel word for an assembler instruction an AT&T alternative).
It is possible to instruct GCC to use the Intel dialect, but it is still a strange way to code assembler, and a way that only works on GCC.
I'm going to make this a serious recommendation - move to Visual Studio. It's free, it is for Windows, you can install it with Clang (for better C++ compliance, though VS is quite decent up to C++17).
I'll put it this way - I so much despise the AT&T dialect, and GCC's approach to inline assembler, that I'm not willing to help anyone learning both at once.
If you're going to make sense of inline assembler on Windows, you must, absolutely must use Visual Studio.
@jonnin's post is an example as to why this is important.
Now, consider this small MASM example taken from Microsoft's documentation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
; POWER.ASM
; Compute the power of an integer
;
PUBLIC _power2
_TEXT SEGMENT WORD PUBLIC 'CODE'
_power2 PROC
push ebp ; Save EBP
mov ebp, esp ; Move ESP into EBP so we can refer
; to arguments on the stack
mov eax, [ebp+4] ; Get first argument
mov ecx, [ebp+6] ; Get second argument
shl eax, cl ; EAX = EAX * ( 2 ^ CL )
pop ebp ; Restore EBP
ret ; Return with sum in EAX
_power2 ENDP
_TEXT ENDS
END
| |
Now, compare that to this C inline assembler using Visual Studio
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
// Power2_inline_asm.c
// compile with: /EHsc
// processor: x86
#include <stdio.h>
int power2( int num, int power );
int main( void )
{
printf_s( "3 times 2 to the power of 5 is %d\n", \
power2( 3, 5) );
}
int power2( int num, int power )
{
__asm
{
mov eax, num ; Get first argument
mov ecx, power ; Get second argument
shl eax, cl ; EAX = EAX * ( 2 to the power of CL )
}
// Return with result in EAX
}
| |
It may take a while to compare, but notice where in the MASM example there is a "mov eax..." instruction, a second instruction, mov ecx..., and then a shl eax.... the same sequence you see in the C inline assembly example. They are the same function, multiplication by a power of 2.
...notice how they look nearly the same
That doesn't work that way in GCC, and it will confuse and frustrate your ability to learn inline assembler.
Move to Visual Studio. That isn't a suggestion at this point. If you want more help, it would be a requirement for most of us.
Once you know inline assembler using Visual Studio, you can
then consider adapting to GCC's horrible mess of a method, because at
that point you have only one thing to learn (GCC's method), and the rest will be more recognizable.
The Visual Studio (Microsoft) approach to inline assembler so much resembles regular assembler, that you can almost intermix the two freely - while it also matches what you might read on x86/64 assembler from all other sources.
That won't work with GCC - they use slightly different keywords, and a mess of a syntax for wrapping the stuff up.
It is also worth noting that when you use assembler, inline or not, you're playing with fire. You will get burned, and it will be confusing for a while. You are working at a level where instructions execute in the billions per second speed. You are in rather direct control of the CPU at the hardware level, though still subject to the restrictions placed on you by the operating system. Anything one can screw up in C can be screwed up on a whole new level in assembler. Debugging is generally quite more of a pain.
You are turning to the dark side. It is a pathway to the unnatural. :)