Author Topic: Tip do avoid errors when linking with TLINK  (Read 6903 times)

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Tip do avoid errors when linking with TLINK
« on: January 20, 2023, 11:33:56 AM »
For MS-DOS you should inform NASM about the CLASS of your sections to avoid some errors with TLINK.

_TEXT has the class CODE
_DATA and _BSS has the class DATA

like this:

Code: [Select]
  section _TEXT class=CODE

  section _DATA class=DATA

NASM don't use class strings for OBJ file and TLINK can fail. This is particulary useful with mixing Turbo C/Borland C++ code with asm, using NASM. Example:
Code: [Select]
// test.c
#include <stdio.h>

extern int f( int );

int main( void )
{
  printf( "%d\n", f( 2 ) );

  return 0;
}
Code: [Select]
; f.asm
  bits 16

struc fstk
    resw  1   ; return address
.x: resw  1   ; argument
endstruc

  section _TEXT

  global _f

_f:
  mov   ax,[esp+fstk.x]  ; YEP! ESP... it is valid!
  add   ax,ax
  ret
Code: [Select]
C:\WORK> nasm -fobj f.asm -o f.obj
C:\WORK> bcc -O2 test.c f.obj
Borland C++  Version 3.1 Copyright (c) 1992 Borland International
test.c:
Turbo Link  Version 5.1 Copyright (c) 1992 Borland International
Error: Fixup overflow at _TEXT:0005, target = _f in module test.c
Changing the section to:
Code: [Select]
  section _TEXT class=CODEWill link perfectly.

BTW, I think I got a strange behavior with NASM 2.16... If I put the section before de declaration of the struc I got a warning of section redefinition...
« Last Edit: January 20, 2023, 02:44:32 PM by fredericopissarra »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Tip do avoid errors when linking with TLINK
« Reply #1 on: January 20, 2023, 08:07:07 PM »
BTW, Turbo C 2.01 & Borland C++ cdecl calling convention is to push everything to the stack (as predicted) from right to left, before the call, but BX don't need to be preserved by the called routine. Only BP, SI and DI (and, of course, SP). And, the caller cleans up the stack.

As in i386 calling convention, the functions has the prefix '_', unless you use fastcall calling convention, which puts an '@' prefix (and uses AX,DX and BX registers are the 3 first arguments).

If you are into Turbo Pascal, the convention is the same, but the arguments are pushed from left to right and the called routine cleans up the stack (as far as I know there's no 'fastcall' convention).