News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Linking Turbo C and Assembler

Started by GavinO, January 18, 2005, 11:53:01 PM

Previous topic - Next topic

GavinO

I'm attempting to link object files generated by Turbo C 2 with object files out of NASM using TLINK (the turbo c linker).  I'm linking to a COM format minus the COM headers, because I just need straight up code (I load the program with a boot sector from a floppy disk and jump into it).  I've got everything working fine, except that addresses to data (for example, a function is passed a char pointer to point to a string) are given in a segment other than the code segment (my current test program has the string begin at address 0x004C, but the result from the linker passes 0x000C).  This causes problems, as the segment registers are all set up to point to the same segment.  This is the series of compile commands I use:

nasm -f obj asm_code.asm
tcc -mt -c c_code.c
tlink /t c_code.obj asm_code.obj,program.bin

If anyone has any ideas of what might be wrong, I'd love to hear them.

Tedd

If you get nasm to output a COFF object file instead of flat binary then this might help - it gives the linker information on where you want things to be, such as data addresses etc.
No snowflake in an avalanche feels responsible.

thomasantony

Hi,
    I think this post will fit here. I don't want to start another topic for it. I can't find the tlink exe in by pack of turbo C. The file that came with TASM is corrupted. Can someone zip up the file and attach it? Its not for programming or anything. I just want to compile and check out some OSes(is that the correct plural form) I downloaded from the net. And you can check out this Os to see how to mix Turbo C and NASM

http://www.geocities.com/sohalnk/data/links.htm

Thomas Antony :U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

Jibz

Tedd,

TLINK is a Borland tool, so it's using the OMF format and most likely doesn't understand COFF. At any rate, the OMF object format also contains information about relocation, so this probably isn't the problem.

GavinO,

A 16-bit com executable does not have any headers, it's a straight binary format loaded at CS:100h. Are you sure you are not linking to exe format?

GavinO

The /t switch for tlink specifies that it should create a COM file, and using an extension other than .com will generate a file organized at CS:0000h. I've looked at the disassembly, and its generating exactly what I want except for addresses referring to data.  I tried the /i switch ('initialize all segments') thinking it might set up ds the way it seems to expect it, but that had no effect on the output.

BigDaddy

cs es ds ss are all be pointing to the same segment, I hope.  So, if the addresses are off by a certain amount, the only thing I can think of is that you've grouped segments together, then used an offset.  In masm mode (but maybe only when quirks is turned on) you'll get the offset from the segment, not the group.  pain in the neck.  If that's the case, either LEA or use OFFSET GROUP:var1. 

GavinO

The addressing problem is happening in the part compiled from C, not the assembler part.  I have a print function (in asm) that takes a char pointer as an argument.  The disassembly of the call to this function is:

mov ax,0xC
push ax
call _print

However, the string is actually at 0x4C.  It looks like the linker put the compiled C stuff, and then my assembled asm functions, and then the data, but ignored the asm functions when calculating the addresses of the data.

MichaelW

GavinO,

What does the map file generated by the linker show (with /m and /s if supported)? Does your ASM module have its own data? If it does, then how much data and is the data defined in a data section (segment)?
eschew obfuscation

GavinO

Looking at that, it put the code from the C file, followed by the code from the asm file, both in segment 0, then the data from the C file in segment 4.  There's also BSS from the C file (that's unitialized space, right?) at segment 5.  I thought that the tiny memory model (which I compiled the C code with) forced the code and data into the same segment?

BigDaddy

How about extern statements?  and did you put an underscore before the external names?

MichaelW

Quote from: GavinO on January 19, 2005, 06:40:33 PM
The addressing problem is happening in the part compiled from C, not the assembler part.  I have a print function (in asm) that takes a char pointer as an argument.  The disassembly of the call to this function is:

mov ax,0xC
push ax
call _print

However, the string is actually at 0x4C.  It looks like the linker put the compiled C stuff, and then my assembled asm functions, and then the data, but ignored the asm functions when calculating the addresses of the data.
The string is at offset address 4Ch? If you run the program in a debugger, is it modifying the value in DS at startup? Specifically, at the point of the code shown above, what value is loaded into DS and is it different from the value loaded into CS? Perhaps Turbo C is producing a non-standard COM file.
eschew obfuscation

GavinO

The generated program starts off calling into the first subroutine, no segment setup involved.  Its not technically a COM file that's being generated; its a COM file with no COM header on it (the first 100h bytes aren't added, it starts right with the program code org'ed at 0).

MichaelW

The first 100h bytes are not added to a COM file. The org 100h effectively reserves 256 bytes in the program's address space for the PSP provided by the loader. How are you getting TC to generate an org 0 executable? If the origin does not match the load address it probably would not affect code labels, but it would affect data labels. Also depending on what your C module is doing, it may depend on components in the PSP (file system and environment access, and the Critical Error, Control C, and terminate vectors).

eschew obfuscation