How to call pascal from assembler
How to call pascal from assembler
Hello. I have a problem. if i using C i do asm file with something like:
[BITS 32]
[EXTERN KERNEL_MAIN]
[GLOBAL _start]
_start:
mov esp, 0x200000-4
call KERNEL_MAIN
and C file with
void KERNEL_MAIN() {
//code
}
But when i try used the same with pascal(in start of program i have
program KERNEL_MAIN; ) in linking i have startup.asm:(.text+0x6): undefined reference to `KERNEL_MAIN'
Is anybody know how to call pascal fuctins from assembler? I'm use freepascal
P.S. Sorry for my English. My native language is Ukrainian
[BITS 32]
[EXTERN KERNEL_MAIN]
[GLOBAL _start]
_start:
mov esp, 0x200000-4
call KERNEL_MAIN
and C file with
void KERNEL_MAIN() {
//code
}
But when i try used the same with pascal(in start of program i have
program KERNEL_MAIN; ) in linking i have startup.asm:(.text+0x6): undefined reference to `KERNEL_MAIN'
Is anybody know how to call pascal fuctins from assembler? I'm use freepascal
P.S. Sorry for my English. My native language is Ukrainian
Re:How to call pascal from assembler
It is very possible that your Pascal compiler is adding a prefix/suffix to its symbols, or maybe even mangling the procedure names just as C++ (for example, my [tt]void Kernel::Kernel::Panic(const char*)[/tt] translates as [tt]_ZN6Kernel6Kernel5PanicEPKc[/tt]).
If you are using the GNU toolchain and your Pascal compiler outputs an object format usable by the GNU binutils, you can see what are your procedure names being mangled to:
Objdump will show you the disassembly of the code sections of the file the Pascal compiler wrote, and it should contain the procedure names just as assembler expects you to call them.
If you are using the GNU toolchain and your Pascal compiler outputs an object format usable by the GNU binutils, you can see what are your procedure names being mangled to:
Code: Select all
yourPascalCompiler kernel_main.pas -o kernel_main.o
objdump -d kernel_main.o
Re:How to call pascal from assembler
I think something likeLinuxMan wrote: Is anybody know how to call pascal fuctins from assembler? I'm use freepascal
Code: Select all
unit KernelMain;
interface
implementation
procedure kernel_main; [public, alias: 'KERNEL_MAIN'];
begin
...
end;
end.
Re:How to call pascal from assembler
Note that when you start working with arguments that you have to push them in inverse order compared to what pretty much all internet tutorials do. Also, if you call ASM from Pascal, the called function is responsible for removing the arguments, using "ret <n>". You can try using some form of objdump to see what the actual name is of the function, use "objdump -t".
Re:How to call pascal from assembler
Thank you, Habbit. My function is named "THREADVARLIST_P$KERNEL_MAIN"
Re:How to call pascal from assembler
You're welcome
I had similar problems when I set my loader: the linked could not found the [tt]kmain[/tt] function... After toying a bit with objdump, I found its name was being mangled to [tt]_Z5kmainmRN9Multiboot8BootInfoE[/tt].
Many static typed languages that support function overloading based on its full signature (its name and the parameters it takes instead of just the name) mangle the "official procedure names" to include that signature. That way, I can have a func(int) and another func(char*): C++ would mangle those names to something including the argument types so they would not conflict at the assembly level.
However, when you want to interface with assembly (and, particularly, call your procedures from it), you need a way of knowing what a function name will be mangled to, which in C++ is very difficult because there is no standard about name mangling and even GCC switches behaviours between versions.
In my case I had an easy workaround: the C++ option [tt]extern "C"[/tt]. Prefixing a function with such an attribute makes the compiler to use C naming for that function. C functions are usually just prefixed with an underscore (i.e., my kmain would be _kmain), or even no prefix, depending on the compiler.
As I don't know Pascal, I can't point out anything like that for you: the best I can tell you is to keep using [tt]objdump -t[/tt] to see the symbol table, but there seems to be an interesting suggestion already in the forum:
I had similar problems when I set my loader: the linked could not found the [tt]kmain[/tt] function... After toying a bit with objdump, I found its name was being mangled to [tt]_Z5kmainmRN9Multiboot8BootInfoE[/tt].
Many static typed languages that support function overloading based on its full signature (its name and the parameters it takes instead of just the name) mangle the "official procedure names" to include that signature. That way, I can have a func(int) and another func(char*): C++ would mangle those names to something including the argument types so they would not conflict at the assembly level.
However, when you want to interface with assembly (and, particularly, call your procedures from it), you need a way of knowing what a function name will be mangled to, which in C++ is very difficult because there is no standard about name mangling and even GCC switches behaviours between versions.
In my case I had an easy workaround: the C++ option [tt]extern "C"[/tt]. Prefixing a function with such an attribute makes the compiler to use C naming for that function. C functions are usually just prefixed with an underscore (i.e., my kmain would be _kmain), or even no prefix, depending on the compiler.
As I don't know Pascal, I can't point out anything like that for you: the best I can tell you is to keep using [tt]objdump -t[/tt] to see the symbol table, but there seems to be an interesting suggestion already in the forum:
nick8325 wrote:Code: Select all
procedure kernel_main; [public, alias: 'KERNEL_MAIN']; begin ... end;
Re:How to call pascal from assembler
iirc pascal supports a [tt]cdecl[/tt] option placed like so:Note that when you start working with arguments that you have to push them in inverse order compared to what pretty much all internet tutorials do.
[tt]procedure some_kernel_function; [public, alias: 'some_kernel_function']; cdecl;
begin
...
end;[/tt]
Which should allow you to pass parameters C++-style.
I wish you the best of luck trying to write an OS in Pascal; it's a very unconventional project and I will enjoy seeing your results.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:How to call pascal from assembler
Here's the FAQ page you've all been waiting for :
Doing a kernel in Pascal
i pushed as much as i could retrieve, but you're open to tell what you know about Pascal OSDev'ing there too
Doing a kernel in Pascal
i pushed as much as i could retrieve, but you're open to tell what you know about Pascal OSDev'ing there too
Re:How to call pascal from assembler
You're the man, Pype!! (or the woman, I can't tell from that Yoda pic). Now, let me write the "Doing a kernel in PHP 5" FAQ page ;DPype.Clicker wrote: Here's the FAQ page you've all been waiting for :
Doing a kernel in Pascal
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:How to call pascal from assembler
The man, indeed. If you know of a woman who has spent 10 years of hobby on writing a OS kernel, and who is moderator of an OSdev' forum where she cumulates +5000 posts, please, tell her .... that i'm engaged already ;DHabbit wrote: You're the man, Pype!!
Re:How to call pascal from assembler
Heh, I don't think she'd reveal her gender for fear of being propositioned by every unattached guy who visits here ;D My other half is picking up stuff scarily quickly though, she's never done computer stuff before and yet picked up binary counting and addition with a mere 10 minute intro from me while we were walking somewhere with no paper to demonstrate anything on. I'll make a geek chick out of her yet
Re:How to call pascal from assembler
You have pretty good English for an internet user. Don't worry about it.LinuxMan wrote: Hello. I have a problem. if i using C i do asm file with something like:
[BITS 32]
[EXTERN KERNEL_MAIN]
[GLOBAL _start]
_start:
mov esp, 0x200000-4
call KERNEL_MAIN
and C file with
void KERNEL_MAIN() {
//code
}
But when i try used the same with pascal(in start of program i have
program KERNEL_MAIN; ) in linking i have startup.asm:(.text+0x6): undefined reference to `KERNEL_MAIN'
Is anybody know how to call pascal fuctins from assembler? I'm use freepascal
P.S. Sorry for my English. My native language is Ukrainian
The actual answer here is that when you write your Pascal kernel as...
Code: Select all
program Kernel;
uses Console,Other,System,Etc;
var
stuff: type;
begin
...
end.
I'll give you an extra tip for coding in Free Pascal: somewhere in your code, declare something like:
Code: Select all
var
btInitialHeap: array [0..$100000-1] of byte;
function KMalloc(lwSize: longword): Pointer;
const
lwAllocatedInitial: longword = 0;
begin
Result:= nil;
if Length(btInitialHeap) - lwAllocatedInitial >= lwSize then
begin
Result:= @btInitialHeap[lwAllocatedInitial];
Inc(lwAllocatedInitial,lwSize);
end;
end;