Problem passing arguments from asm to C code...

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
drwatts

Problem passing arguments from asm to C code...

Post by drwatts »

Hey, I have a bit of a problem with my asm interrupt handler entry point calling the c function and passing it appropriate values.

I thought I was doing it just fine... each entry pushes a 0, and then a int number (unless there should be an error code)  But it pushes these and then jumps to a point in the asm code which cli's and then calls the c function.

Using simics, I have a copy of the stack as it stands, after doing a keyboard interrupt. (Keep in mind this is AMD64 code, all stack pushs/pops are 64-bit)

rsp = 0x80000f88
rbp = 0x80000fa8

showing from 0x80000f88 and going up
0x10175b    <- Return Address    0x80000f88
0x80000ff8  <- Stack Pointer     0x80000f90
0x1a        <- ??                0x80000f98
0           <- ??                0x80000fa0
0x80000ff8  <- Stack Pointer     0x80000fa8
0x102222    <- ?? Some Address   0x80000fb0
0x21        <- The Number I want 0x80000fb8
0           <- The Error Code    0x80000fc0

Okay, my int handler entry point looks like this:

ioapic_01:
pushq $0x0
pushq $0x21
jmp asm_int_handler

The generic function for all interrupts
-------------------------------------------
asm_int_handler:
cli
        call interrupt_handler
sti
iretq

interrupt_handler looks like this
------------------------------------------
void interrupt_handler(unsigned long error_code, unsigned long interrupt_number)
{
unsigned long cr2_value;
asm("hlt");
// Other code that doesn't matter right now


All I want is to get the correct info..

Any ideas?
Thanks in advance
drwatts

RE:Problem passing arguments from asm to C code...

Post by drwatts »

Well, I figured out my problem, but maybe somebody can explain why...


I added the code to asm_int_handler:

cli
popq %rdi
popq %rsi
call interrupt_handler
sti
iretq

I have read somewhere about preserving rdi, rsi, and rdx... but why?

If somebody can explain this, it would be terrific.

Thanks
dr_watts

Still Having Major Problem

Post by dr_watts »

It seems that no matter what we try, calling to C code from assembler is acting irregular.  It does not attempt to check the stack, it instead loads from rdi (64-bit edi).  We tried using cdecl  and stdcall in front of the functions, to no avail.   gcc said it was just ignoring them.  Could this just be a gcc glitch that we have to live with?
BillFarber

RE:Problem passing arguments from asm to C code...

Post by BillFarber »

Your Code:
>cli
>popq %rdi
>popq %rsi
>call interrupt_handler
>sti
>iretq

You are totally screwing up the stack for that frame.

Your initial problem was that the C routine is expecting two params, but you aren't passing any. Your intermediate int handler (above) needs to get the params passed to it by the entry point, and pass them to the c-handler. Just leaving them on the stack and (effectively) changing the stack pointer is a kludge at best.

should probably look something like this:

push ebp     ; save whatever is in the register coming in
mov ebp, esp ; get the current stack frame and put it in a register for use after further pushes and pops

mov eax,[ebp+12] ; get the SECOND param
push eax         ; push it onto the stack for the call to c
mov eax,[ebp+8]  ; get the FIRST param
push eax         ; push it onto the stack for the call to c
call interrupt_handler
pop eax
pop eax

sti
iretq
eucar

RE:Problem passing arguments from asm to C code...

Post by eucar »

We've discovered why our C functions seem to want to take their arguments through registers rather than the stack.  The ELF ABI for x86-64 (AMD64) systems actually contains many optimizations, among them is passing function parameters in registers instead of strictly on the stack.
Post Reply