Page 1 of 1

Using assembly inc gcc (Problem)

Posted: Wed Jul 03, 2002 7:21 am
by Willy
So, how does that happen. Like for example I have this kindof thingy:

int gotoxy(int x, int y)
{
//Asm code here
}
I know that I have to use gas syntax, but thats the problem,
How can I use 'x' and 'y' in my code, everything else works.
Example code would be nice :)

Re:Using assembly inc gcc (Problem)

Posted: Wed Jul 03, 2002 11:28 am
by Schol-R-LEA
If the assembly code takes up the entire body of the function, it probably would be better to write it as a separate assembly function and link it to the C code afterwards.

Either way, I would expect that reading the arguments from the stack would be done by using the appropriate offset from the frame pointer. In NASM syntax, it would be something like

Code: Select all

mov EAX, [ebp + 8]          ; EAX = x
mov EBX, [ebp + 12]        ; EBX = y
which in AT&T/gas syntax would (I think) be

Code: Select all

movl   8(%ebp), %eax     // %eax = x           
movl 12(%ebp), %ebx     // %ebx = y 


The offsets start at 8 because the return pointer and the old frame pointer have to be pushed onto the stack after the arguments are. In pure assembly, you have to remember to manually push the EBP, set the EBP to the current stack pointer (ESP), and then restore it at the end of the function:

Code: Select all

; NASM syntax 
push EBP
mov EBP, ESP
...                      ; your function code here
pop EBP             ; restore the calling function's frame pointer
In inline assembly, this should be all handled by the C compiler.

This is only a rough outline of how you'd do it; you'll have to look up the details of the frame buffer, etc. yourself to get the correct offsets and so forth.

As always, corrections are appreciated, especially in this case since I don't know the AT&T syntax very well and almost certainly got it wrong. :-\

Re:Using assembly inc gcc (Problem)

Posted: Thu Jul 04, 2002 5:24 am
by Pype.Clicker
a trick for you: don't learn the AT&T syntax:
just write the code you wish for NASM, assemble, and disasemble with objdump -d 8)

Re:Using assembly inc gcc (Problem)

Posted: Thu Jul 04, 2002 5:36 am
by Pype.Clicker
here's a sample code of my kernel using inline assembly:

static __inline__ dword peek(word sel,void *off)
{
dword ret;
asm("push %%es;mov %1,%%es;"
"mov %%es:(%2),%0;"
"pop %%es":"=r"(ret):"g"(sel),"r"(off));
return ret;
}
  • try always to use inline functions (will be expanded inside of the caller code and save a lot of stack ops). Cute&pasting assembly code through your kernel will give you headaches.
  • the asm() instruction of GCC is split in 3 parts separated by columns "operations":<result storing>:<inputs>
  • use "info gcc" if you need to do complex stuffs...
What GCC inline assembly can do for you is selecting registers and operands that will best fits its actual registers usage based on some informations you gave it such as "ret must be a general register", or "my code spills ecx, don't rely its value to remain constant", which saves you to write lot of useless pushes and pops.

now what does my code mean (in nasm):
push es
mov es, <sel=any general register or memory location, left to the appreciation of the compiler>
mov <ret=any general register ...>,[es:<off in any general register>
pop es

one possible code generation if not inlined would be:

push ebp ;;;; skipped if inlined
mov ebp, esp ;;;;
push es
mov es,[ebp+8]
mov edx,[ebp+12]
mov eax,[es:edx]
pop es
pop ebp ;;;;
ret ;;;;

Now if the caller code widely uses edx, the compiler could choose to use ecx instead, or to push/pop edx ... regarding to what it prefers ;)

Just in case, do *always* check the code gcc generated matches the code you wanted to write (at least once), using gcc -S or objdump -d ...

Re:Using assembly inc gcc (Problem)

Posted: Mon Jul 15, 2002 6:43 pm
by Schol-R-LEA
If it helps, I found a page explaining the use of inline assembly in gcc, as well as one on GAS assembly programming in general. I haven't looked it over closey yet, however, so I can't promise anything.