Page 1 of 1

Problem calling Assembly procedure from C

Posted: Tue Feb 21, 2012 8:16 pm
by JonOS
Background:
I have compiled the cross-compiler in CYGWIN and it functions.
In REAL-MODE assembly I can setup the GDT and get into PMODE with the interupts disabled (cli).
Then I write confirmation out to video twice in assembly calling an assembly procedure "ax_vid_32".
In between the video ouputs I can call an externally defined c "main", which is an empty function:

Code: Select all

int main()
{
  return 0;
}
So,I successfully return from c to the second video output.
Both video outputs are visible and the program hangs with a "hang: jmp hang"
There are three files:
1. Second.asm (sets up GDT, switches to PMODE outputs to video via "ax_vid_32" in UTIL32.ASM and calls the "main" in kernel.c
2. kernel.c (which calls the video out routine "ax_vid_32" in UTIL32.ASM)
3. UTIL32.ASM (containing "ax_vid_32")
These won't link properly with this:

Code: Select all

i586-elf-ld -T link.ld -o SECOND.BIN SECOND.o kernel.o UTIL32.o 
I get undefined references. So I partially link SECOND.o and kernel.o with the "-r" option and the link that result to UTIL32.o with no problems

Problem:
I want to call the video output procedure in assembly to confirm I can do something in the main function
that calls assembly procedures. But the pc (virtual machine in VMware) crashes (triple-fault?) after the first video output.
The modified "main" looks like this:

Code: Select all

extern void ax_vid_32();

int main()
{
  ax_vid_32();
  return 0;
}
I realize I may need to supply more information for a someone to understand what I am doing wrong.
If you would be so kind please let me know what else to provide.
This is my first use of the forum.

Jon

Re: Problem calling Assembly procedure from C

Posted: Tue Feb 21, 2012 8:50 pm
by thepowersgang
Within the first two lines of assembly code, it's obvious that you don't know the difference between real mode and pmode.

You're updating DS, using ES without setting it, only using 16-bit registers and doing excessive pushes/pops.

You should only ever need to set DS once, and that's just after switching to pmode.

Answer to your question: I blame the "mov word bp,[es:vid_placement]" in util32.asm, but there's so many potential errors in that code, it's hard to be sure which one causes the crash.

Re: Problem calling Assembly procedure from C

Posted: Tue Feb 21, 2012 9:01 pm
by JonOS
the pushing/popping of bp/ds is just to make sure that what I am doing in the assembly procedure called from c doesn't screw up the c calling convention that I interpret as saying "don't change those or you have problems when returning from c".
I set es when I first jump to "clear-pipe".
the 16 bit part: I am only setting the segment selectors ds, es
I was under the impression that you can only set the visible part of these registers and they are only 16 bits.
Anyway, any ideas on why a rather simple call to assembly routine from c crashes the machine?
Yes, clearly I don't know what I am doing! Hence, the problems I am having! :D

Re: Problem calling Assembly procedure from C

Posted: Wed Feb 22, 2012 1:24 am
by Solar
Well, thepowersgang already pointed it out, didn't he? Your understanding of Assembler, most notably the difference between Real Mode and Protected Mode, is lacking.

Hence, find an Assembler resource that talks about this, and brush up your skills. Learning 80x86 Assembly lists some recommended resources.

Re: Problem calling Assembly procedure from C

Posted: Wed Feb 22, 2012 4:13 pm
by JonOS
Solar --

I am not sure what you are refering to when you say my understanding of the difference between real-mode and pmode is lacking. The part where I said the visible part of the segment registers are 16 bit or the part where I explained that I had set es? I realize that excessive pushing/poping can be irritating to read through in code ... but knowing the particular part of my code that convinced you I didn't know the difference between real-mode and pmode would be helpful. Can I convince you to articulate it?
I understand you took time to comment so it seems you want to help in some way ... but I couldn't extract anything useful from either of your comments.

Re: Problem calling Assembly procedure from C

Posted: Wed Feb 22, 2012 5:57 pm
by Combuster
You are using protected mode, yet you still think in the ways of a 16-bit DOS app. Your C code will hate you for that because it expects flat segmentation with DS=ES=SS=pointing to zero. Next you mix up segments causing wrong addresses and accesses of uninitialized areas.

I see no 32-bit registers apart from the bare minimum to get it working, and I see absolutely no 32-bit addressing forms. That is a very strong indication that you have never ever written 32-bit assembly code before (and therefore, have no idea how it is meant to be used).