Hello. I want to test my basic knowledge of ASM with a simple add(a, b) function, that adds a and b using assembly. I have never been able to use inline ASM, because I couldn't figure out how. Can someone direct me to a very, VERY basic tutorial of inline ASM? I'm sure I'm leaving out some major detail as to what my operating system is or whatever. If that is important, please explain why in simple terms. Thanks.
it is rarely useful to do more than 5 or so operations at a go. Most of the speedups you can do with it these days are to force the machine to do something simple that is not supported in c++ because its not on every chip, for example x86 has an endian reverse command that not all CPU have which is much faster than shuffling bytes around.
you probably want to either let C++ handle the function part (you can do the innards) or be very careful with the calling conventions stuff.
Seriously, if you want to program in asm, you need to up your game.
This will be so much harder than programming in the higher level languages. If you don't have the grit to dig into problems hard, it's not going to work out. Assembly does not take prisoners!.
Like showing which sites you've studied, what you've tried, what results (or lack thereof) you've seen.
Also write very small functions in C, compile with the -S flag and study the results.
This can be an education in itself.
Adding -O2 to the compile line reduces the heart of the generated code to this:
1 2
leal (%rdi,%rsi), %eax
ret
It takes advantage of the "load effective address" instruction and the fact that the parameters are passed in rdi and rsi and the return value is meant to be in eax.
Thanks, everyone. I will study your answers more thoroughly and see what I can learn.
@salem c: I have tried searching on the web, but the fact that I don't know much about
processors and such made it a little hard for me to understand what syntax to use and
what-not. Thanks for making me aware of the obvious lack of research in my post. I am
going to do some research before I ask more questions on the subject.
int increment(int a) {
int result, increment = 1;
__asm__("addl %%ebx, %%eax"
: "=a" (result)
: "a" (a), "b" (increment));
return result;
}
I don't know whether it is the best way to do this or not, but it works. :D
I don't understand the "=a", "a" and "b" parts yet, but I'll keep learning.
Ah, alright. I've noticed that if I change %%eax to %%edx, it only works if I change "=a" to "=d" and "a" to "d". I partly understand that, actually. It is saying that the output of eax + ebx (a + b) will be stored in eax (a). Thus, the output of edx + ebx (d + b, not a + b) will be stored in edx (d). If this is true, how many e*x registers are there? And do I always use the middle letter?
you will need to start reading an x86 manual.
it does not work that way. some registers cannot be added together, and the result is often the A register.
A,B,C,D are the main registers. al and ah are 8 bit, ax and bx etc are 16 bit, eax ecx etc are 32 bit, and rax, rbx, etc are 64 bit. al is part of ax is part of eax is part of rax .. they are not distinct things but a way to slice up the same 64 bit circuits.
some are used more for indexing/memory, ax and bx are used more for computation, ax tends to be the result, ... instructions have specific targets and side effects that you need to be aware of them. In some ways registers are like global variables and you need to trace carefully what functions use which ones and how.