Linking and addressing issues
Posted: Wed Jan 04, 2023 9:18 am
Hello everybody.
Thank you for your time reading this topic.
A few days ago, I decided to pick up my old hobby, writing an Operating System. And although I was very far with the previous OS I wrote, I decided it
would be fun to start all over. Besides, having more knowledge and experience now should make it a breeze, shouldn't it?
Well, I was (very very) wrong). But that is a topic for another day...
At this moment, I am writing my secondary bootloader. This loader is loaded by the primary bootloader. My toolchain for writing this piece of software
is nasm, combined with the Borland turbo c++ 3.0 compiler and the turbo linker.
Everything compiles and links well(ish). I try to link all source files into one com/binary executable. Luckely, the linker understands that the entrypoint
has to be at 0x0000.
The loader executes fine, until a string is passed to the print_string function. Looking in my bochs debugger, it seems that a totally wrong offset is passed to
the print_string function. Looking at my map-file I understand what's going wrong; the linker is handling the data segment as a separate segment, while I always
thought that a com-file has only one segment.
The question now is, how do I circumvent this kind of segment handling? Below the output of the linker in map-format:
Start Stop Length Name Class
00000H 00089H 0008AH _TEXT CODE
0008AH 000B0H 00027H _DATA DATA
000B2H 000B2H 00000H _BSS BSS
Detailed map of segments
0000:0000 0050 C=CODE S=_TEXT G=(none) M=LOADHEAD.ASM ACBP=28
0000:0050 003A C=CODE S=_TEXT G=(none) M=LOADER.C ACBP=28
0008:000A 0027 C=DATA S=_DATA G=DGROUP M=LOADER.C ACBP=48
0008:0032 0000 C=BSS S=_BSS G=DGROUP M=LOADER.C ACBP=48
Address Publics by Name
0000:0003 _CLEAR_SCREEN
0000:0069 _MAIN
0000:0021 _PRINT_CHAR
0000:0050 idle _PRINT_STRING
0000:0037 _SET_CURSOR
0000:0000 idle _START
Address Publics by Value
0000:0000 idle _START
0000:0003 _CLEAR_SCREEN
0000:0021 _PRINT_CHAR
0000:0037 _SET_CURSOR
0000:0050 idle _PRINT_STRING
0000:0069 _MAIN
Thank you for your time reading this topic.
A few days ago, I decided to pick up my old hobby, writing an Operating System. And although I was very far with the previous OS I wrote, I decided it
would be fun to start all over. Besides, having more knowledge and experience now should make it a breeze, shouldn't it?
Well, I was (very very) wrong). But that is a topic for another day...
At this moment, I am writing my secondary bootloader. This loader is loaded by the primary bootloader. My toolchain for writing this piece of software
is nasm, combined with the Borland turbo c++ 3.0 compiler and the turbo linker.
Everything compiles and links well(ish). I try to link all source files into one com/binary executable. Luckely, the linker understands that the entrypoint
has to be at 0x0000.
The loader executes fine, until a string is passed to the print_string function. Looking in my bochs debugger, it seems that a totally wrong offset is passed to
the print_string function. Looking at my map-file I understand what's going wrong; the linker is handling the data segment as a separate segment, while I always
thought that a com-file has only one segment.
The question now is, how do I circumvent this kind of segment handling? Below the output of the linker in map-format:
Start Stop Length Name Class
00000H 00089H 0008AH _TEXT CODE
0008AH 000B0H 00027H _DATA DATA
000B2H 000B2H 00000H _BSS BSS
Detailed map of segments
0000:0000 0050 C=CODE S=_TEXT G=(none) M=LOADHEAD.ASM ACBP=28
0000:0050 003A C=CODE S=_TEXT G=(none) M=LOADER.C ACBP=28
0008:000A 0027 C=DATA S=_DATA G=DGROUP M=LOADER.C ACBP=48
0008:0032 0000 C=BSS S=_BSS G=DGROUP M=LOADER.C ACBP=48
Address Publics by Name
0000:0003 _CLEAR_SCREEN
0000:0069 _MAIN
0000:0021 _PRINT_CHAR
0000:0050 idle _PRINT_STRING
0000:0037 _SET_CURSOR
0000:0000 idle _START
Address Publics by Value
0000:0000 idle _START
0000:0003 _CLEAR_SCREEN
0000:0021 _PRINT_CHAR
0000:0037 _SET_CURSOR
0000:0050 idle _PRINT_STRING
0000:0069 _MAIN