Recent

Author Topic: How to export Pascal variables for use by NASM code with i8086 msdos target?  (Read 1103 times)

ecm

  • New Member
  • *
  • Posts: 12
I'm trying to port the LZEXE Pascal+assembly sources to build with FreePascal and NASM, targeting the i8086 msdos platform. They're working on TurboPascal 5.0 + NASM.

After some tweaks to the function definitions all around and the function pointer types in lzutil.pas, as well as renaming the NASM object files to end in an .o filename extension, I get the "Error: Undefined symbol:" for variables declared in the lzexe.pas (var in the .pas) but used in exepack2.nas (extern in the .nas).

According to https://docs.freepascal.org/docs-html/current/prog/progsu151.html I tried to mark my variables with cvar but this doesn't seem to change the error.

Let me demonstrate with a small example:

Code: [Select]
test$ ls
bin  fpc.sh  lib  test.a  testasm.asm  testasm.o  test.pas
test$ cat fpc.sh
#! /bin/bash

FPCDIR="$(dirname "$0")"
"$FPCDIR"/bin/ppcross8086 -vi -Tmsdos -WmSmall \
 -Fu"$FPCDIR"/lib/fpc/3.2.2/units/msdos/8086-small/rtl \
 "$@"
test$ cat testasm.asm

section CODE public align=16

extern depackersize

global prepare
prepare:
        mov word [depackersize], 26
        retn
test$ cat test.pas

program test;
var depackersize:word;cvar;

procedure prepare;external;
{$L testasm}

begin
        prepare;
end.

test$ nasm -fobj testasm.asm -o testasm.o && ./fpc.sh test.pas
Free Pascal Compiler version 3.2.2 [2021/05/17] for i8086
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: MS-DOS 16-bit real mode
Compiling test.pas
test.pas(3,5) Note: Local variable "depackersize" not used
Linking test.exe
test.pas(10,1) Error: Undefined symbol: depackersize
test.pas(10,1) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
test$

korba812

  • Sr. Member
  • ****
  • Posts: 476
It seems that you should use the "export" modifier.
Code: Pascal  [Select][+][-]
  1. var depackersize:word;export;

ecm

  • New Member
  • *
  • Posts: 12
Thanks, that fixes that problem. I also had to make sure to use "export" in another file (lzutil.pas) and the .pas variables need to be in exactly the same case as the NASM object's references to them.

I have some new problems now, one in cmdline.pas where it tries reading the DOS application command line using a far pointer (it doesn't get the expected string content):

Code: [Select]
cmd:=string(ptr(Prefixseg,$80)^);
The other is lots of warning messages that all match, reading "lzexe.pas(558,1) Warning: Encountered an OMF reference to a section, that has been removed by smartlinking: DATA||" which are caused by lzss.o (renamed output of unmodified lzss.nas) it seems. (If I comment out almost all of this file the warnings disappear.)

Should I post about these problems in new threads?

korba812

  • Sr. Member
  • ****
  • Posts: 476
I have some new problems now, one in cmdline.pas where it tries reading the DOS application command line using a far pointer (it doesn't get the expected string content):

Code: [Select]
cmd:=string(ptr(Prefixseg,$80)^);
The type of string depends on the compiler mode and switches. Maybe in your case the string is of type ansistring instead of shortstring? Try casting to the shortstring type
Code: [Select]
cmd:=shortstring(ptr(Prefixseg,$80)^);

ecm

  • New Member
  • *
  • Posts: 12
I did try with shortstring after finding a mention that the TurboPascal mode changes the default to be a shortstring. Didn't change the behaviour. Also, I assume if that was the problem then I should see some of a (nonempty) command line at the beginning of the longer string type, right? I do not see that.

korba812

  • Sr. Member
  • ****
  • Posts: 476
I don't use the i8086 target (so far) and don't have a cross-compiler for it, but looking at the wiki (https://wiki.freepascal.org/DOS#Huge_pointers) page it seems that the Ptr returns a huge pointer. Try this:
Code: Pascal  [Select][+][-]
  1. type
  2.   PHugeString = ^ShortString; huge;
  3. ...
  4.   cmd:=PHugeString(ptr(Prefixseg,$80))^;
  5.  

Also, I assume if that was the problem then I should see some of a (nonempty) command line at the beginning of the longer string type, right? I do not see that.
If you mean AnsiString then it is very different from ShortString - a variable of type AnsiString is a pointer.
« Last Edit: June 20, 2025, 11:16:56 pm by korba812 »

ecm

  • New Member
  • *
  • Posts: 12
I tried that both with huge and far. Very similar results. According to my understanding of DOS memory segmentation I do need a far pointer, not a huge pointer. Albeit a huge pointer would work in the same way if either worked.
« Last Edit: June 21, 2025, 12:15:50 pm by ecm »

ecm

  • New Member
  • *
  • Posts: 12
I posted about the string far pointer read in another thread and eventually found I should use large memory model to approximate TurboPascal's model, which also fixed reading the command line from the PSP.

In yet another thread I figured out how to fix the "Encountered an OMF reference to a section, that has been removed by smartlinking" warning messages.

 

TinyPortal © 2005-2018