3

I am learning Operating System Development and a Beginner of course. I would like to build my system in real mode environment which is a 16 bit environment using C language.

In C, I used a function asm() to convert the codes to 16 bit as follows:

asm(".code16")

which in GCC's language to generate 16 bit executables(not exactly though).

Question:

Suppose I have two header files head1.h and head2.h and a main.c file. The contents of main.c file are as follows:

asm(".code16");
#include<head1.h>
#include<head2.h>
int main(){
  return 0;
}

Now, Since I started my code with the command to generate 16 bit executable file and then included head1.h and head2.h, will I need to do the same in all header files that I am to create? (or) Is it sufficient to add the line asm(".code16"); once?

OS: Ubuntu

Compiler: Gnu CC

Panther Coder
  • 1,058
  • 1
  • 16
  • 43
  • 4
    I recommend you not use gcc to compile 16 bit code. What you use is a kludge that causes a bunch of problems. – fuz Feb 12 '17 at 18:05
  • [`asm` is not a function](https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html#Basic-Asm) – phuclv Dec 16 '18 at 14:25

2 Answers2

6

To answer your question: It suffices for the asm block to be present at the beginning of the translation unit.
So putting it once at the beginning will do.

But you can do better: you can avoid it altogether and use the -m16 command line option (available from 5.2.0) instead.

But you can do better: you can avoid it altogether.


The effect of -m16 and .code16 is to make 32-bit code executable in real mode, it is not to produce real mode code.

Look

16.c

int main()
{
   return 4;
}

Extracting the raw .text segment

>gcc -c -m16 16.c
>objcopy -j .text -O binary 16.o 16.bin
>ndisasm 16.bin

we get

00000000  6655              push ebp
00000002  6689E5            mov ebp,esp
00000005  6683E4F0          and esp,byte -0x10
00000009  66E800000000      call dword 0xf
0000000F  66B804000000      mov eax,0x4
00000015  66C9              o32 leave
00000017  66C3              o32 ret

Which is just 32-bit code filled with operand size prefixes.
On a real pre-386 machine this won't work as the 66h opcode is UD.


There are old 16-bit compilers, like Turbo C1, that address the problematic of the real-mode applications properly.

Turbo C code generation options

Alternatively, switch in protected mode as soon as possible or consider using UEFI.


1 It is available online. This compiler is as old as me!

Community
  • 1
  • 1
Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
  • 1
    ["Don't Mention the War!"](https://www.youtube.com/watch?v=yfl6Lu3xQW0). The fewer people that know about Turbo-C(++) the better! – Bo Persson Feb 12 '17 at 21:04
0

It is not needed to add asm("code16") neither in head1.h nor head2.h.

The main reason is how the C pre-compiler works. It replaces the content of head1.h and head2.h within main.c.

Please check How `#include' Works for further information.

Hope it helps!

Best regards,

Miguel Ángel