views:

79

answers:

4

I am trying to print a string in a way that's OS-neutral. For example, the program should run the same on Windows as it does on *nix.

Is this even possible? I'm assuming that since the underlying architecture is the same (x86) that the method would be the same. Is it as simple as calling an interrupt?

The reason for this is I'm trying to write a compiler that generates assembly code - at this early point in its development, only a handful of features are present - I'd like to be able to test the generated assembly code in either Windows or *nix. Down the road, it will be impossible to maintain platform-neutrality while generating the same code, but basically all I want to do at this point is print a string.

+2  A: 

Can you link against libc? If you can do that, you should be able to just call printf() and be done with it. An example program can be found at this link.

Carl Norum
But how is linking with `libc` platform-neutral?
George Edison
+1 - I have to agree - you won't be able to use a platform-independent interrupt to perform this - unless by coincidence or perhaps by design interrupt INT 10h is supported on both. Alternatively, create yourself a small library of functions for outputting strings and call the relevant interrupts (if Linux string output is interrupt-based) depending on the platform.
Will A
@George, I would hazard a guess that most platforms have `libc`. Chances are the shell you're running your program from was built with it, for example.
Carl Norum
It's 2010, why are people still talking about interrupts for OS services?
siride
@siride: Because he's writing in assembly. The real question is it 2010, why would anyone still write code in assembly?
slebetman
@siride: How else are you planning to make a system call in assembly?
Nicholas Knight
@Nicholas, almost all system calls have wrapper functions you could call instead of using the interrupts directly. And @slebetman, some of us still write system code.
Carl Norum
@Carl: There's little difference. Syscall wrappers are tissue-thin, still non-portable, invoke the interrupt anyway, and anyone using them ought to understand that fully. In context, Will's statement was quite reasonable, and siride's made little sense.
Nicholas Knight
@sle: Because I'm writing a compiler.
George Edison
On Linux, you can use the VDSO functions that are available to every process to make a system call. On Windows, you aren't even supposed to know that you can make syscalls via interrupts because that's something the native API does, not the Win32 API. But either way, the OSes don't use interrupts anymore, they use instructions like sysenter.
siride
A: 

Pure assembly should not be considered portable between operating systems. There is no universal way to interact with system services from assembly. You shouldn't even assume portability between Unix-like OSes (POSIX doesn't specify a calling convention, though some x86 Unices do use a common convention).

Even in higher-level languages, calling conventions can technically vary from one compiler to the next on the exact same CPU+OS, though usually compilers use whatever convention is specified for the host environment.

See also Wikipedia's page on x86 calling conventions.

Nicholas Knight
A: 

To do this, you'd need to write something similar to a polyglot.

ninjalj
A: 

Sorry, no one has brought up Java?

Xepoch
How is Java an answer to the question? This is a question about assembly language.
George Edison
Shove bytecode through an in-process JVM, solves the libc platform-neutrality in other post.
Xepoch
I'm not writing an in-process JVM - I'm writing a compiler. I see what you're saying though. But using the JVM is not an option.
George Edison