Calling ASM functions from C

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
HuntrCkr

Calling ASM functions from C

Post by HuntrCkr »

OK, here is the situation. My bootloader sets up a pmode stack, loads in a GDT and jumps to my kernel code, which is currently located at 0x10000 physical.
Then the kernel sets up a new GDT. Works fine too. But, I have an asm function called _load_gs.
The C declaration is "extern void load_gs(unsigned int newfs);

asm code is as follows:
_load_gs:
push ebp
mov ebp,esp
xor eax,eax
mov eax, [ds:ebp+4] ; 1st param passed by C according to all docs I have
mov gs,eax
pop ebp
retn

Can anybody tell me what I could possibly be doing wrong?!? From what a routine I wrote tells me, eax contains gibberish, and not the 1st parameter passed by C. BTW, ds and ss are the same.

Thanks for any help
   Hunter Seeker
Schol-R-LEA

RE:Calling ASM functions from C

Post by Schol-R-LEA »

The EBP should offset to a location in the stack segment, not the data segment. Thus, the line where you get the argument should read

mov eax, [ss:ebp+4]

Actually, I don't think you need the segment selector at all, as offsets of EBP default to the stack, IIRC.
carbonBased

RE:Calling ASM functions from C

Post by carbonBased »

Shouldn't matter, though... he said ds and ss are the same selector.

Problem is (I _think_), if ds and ss are the same, then ss is, no doubt, an expand down segment (as is a data segment).

mov eax, [ss:ebp+4]
Is notation assuming an exapand _up_ stack.  In your case, with an exapand down, you're actually accessing part of the stack that hasn't even been written to yet.

You actually want [ss:ebp-4] (is that even possible?  Negative displacements in an address reference?)

Also, "mov gs, eax" should really be "mov gs, ax" seeing as though selectors at 16-bit, and eax is 32.

Jeff
geezer

RE:Calling ASM functions from C

Post by geezer »

>mov eax, [ds:ebp+4] ; 1st param passed by C according to all docs I have

You don't need the override. Also, for 32-bit code, the left-most argument
on the stack frame is at ebp+8 (ebp+0 is the old EBP, and ebp+4 is the
old EIP [return address]). Try this:

mov eax, [ebp+8]
HuntrCkr

RE:Calling ASM functions from C

Post by HuntrCkr »

Thanks geezer, I will remember it for future reference. I solved my problem though by replacing it with inline assembler. I was wondering why the contents of [ebp+4] looked an awful lot like a memory address from somewhere in my kernel.

Thanks for quick replies
  HuntrCkr
Post Reply