Author Topic: Question Problem with "global"  (Read 4880 times)

Offline Guenni60

  • New Member
  • Posts: 1
Question Problem with "global"
« on: March 16, 2016, 03:53:47 PM »
Hello Man and Supporter for NASM.

I had download the Package  nasm-2.11.08-dos
(and some more Packages for other OS's) 
and want to write little Bit Code für 16-Bit-DOS (pur DOS)
as Object-File, which should include in Turbo-Pascal 7 rsp.
Borland-Pascal 7 (patched for RTE 200 because of the notorius
Bug which doesn't run the Progs on Machines faster than  200 MHz).

Now this is the Code:
 
  ; int_fpu.asn
  ; Ausprobier-Programm für die FPU / 80x87
  ; NASM-Assembler-Programm
 
 
  ; Hinweis:
  ; Starte Assemblierung mit 
  ;   NASM  -f bin int_fpu.asn           ; für-DOS Real-Mode
  ;                                      ; Damit erhält man  ein File int_fpu.com (leider in Kleinschrift)
  ;       
  ;   NASM  -f bin int_fpu.asn  -l int_fpu.lst  ; für DOS-Real-Mode
  ;                                             ; Mit dem Parameter -l  erhält man ein Listing-File
  ;                                             ; das neben den Zeilen-Nummer auch den Binär.Code enthält!
  ; Kein "-o int_fpu.obj" angeben!
  ; Sonst erhält man Fehler 47:  .OBJ-Dateiformat  nicht gültig!
  ;
  ;
  ;   
  ;
  ; Hinweise:
  ; Kann man mit NASM Object-Code erzeugen,
  ; der dann von TP7/BP7 eingebunden werden kann ?
  ; Prinzipiell ja!
  ; Dafür dient die Funktion  int2real 
  ; Probleme gibt es noch in Details (siehe oben).
  ;
 
  ; Ansonsten gibt es im PASCAL-Code den  Fehler "Unbekannter Bezeichner"
  ;    beim Aufruf einer Funktion  Int2Real !   
  ; Grund: Dieser Bezeichner ist nicht im Object-Code enthalten!
  ; Nachdem diese Hürde umschifft war, nun  das Problem mit dem  "-o bin"-Format.
  ; Dieser erlaubt eigentlich kein Exportieren von Extern-  u. Global-Bezeichnern ... 
  ;
   ;
  ; Historie:
  ; ... (deleted)
  ; 2016.03.01-02  GEWE-PROJEKTE  GLW  Funktion  Int2Real geändert/erstellt,
  ;                               Fehler: Ungültige PUBLIC-Definition in (diesem) OBJ-File
 
 
  ;
  ; Original-Code für/in/mit NASM:
 
   ;BITS 32                          ; 32-Bit-Modell ( - kein 16-Bit-Model ???
                                     ; Falsch als 'BITS32' angegeben (Siehe Kapitel 6.1)
    BITS 16                          ; 16-Bit-Modell  - siehe Kapitel 6.1   
   
  ; %define PASCAL                   ; Vielleicht nur erforderlich für das Makro-Packet c16.mac ?
                                              ; I think we don't need this Declaration
   
    SECTION .data                    ; Initialisierte Daten
    ;   int32:   dd 1919641698       ; Double-Word  (4 Bytes)   1.919.641.698  1,9 Milliarden 
      ; int64:   dq 1919641698       ; Quarter-Word (8 Bytes)   1.919.641.698  1,9 Milliarden
                                     ; Problem bei/mit NASM:
                                     ; Integer supplied to a DQ-Instruction ...  Daher:
    ;   int64:   dq 1.919641e10      ; Quarter-Word (8 Bytes)   1.919.641*10^10 => 19 Milliarden !
       
   
  ; SECTION .bss                     ; Nicht-initialisierte Daten 
    ;   extern   int32               ; Versuch einer EXTERN-Deklaration von int32  Nicht "extern  int32:dd" !
      ; dbl:     resq 1              ; Ergebnis-Feld  'dbl' vom Type  resq  (Quadword) = 8 Bytes
                                     ; Declare an uninitialized storage space: An Array of 1 Real Number
    ;   extern   erg8                ; Versuch einer EXTERN-Deklaration, umbenannt von 'dbl'
       
   
   ;SECTION code                     ; 'SECTION' ist gleichbedeutend mit 'SEGMENT'
                                     ; '.text' ist gleichbedeutend mit '.code'
    SEGMENT code private align=16    ; 'private' u. 'align=16' eventuell wichtig für DOS ?  Siehe PDF Kapitel 7.4.1
       
 
    ; Neue von GLW erstellte Funktion: 
    global  Int2Real                 ; Funktion im PASCAL-Stil 
   ;global  Int2Real:function        ; Funktion im PASCAL-Stil  Fehler: Object-Format supports no special features for this symbol!
    Int2Real:                        ; function  Int2Real(a : integer; b : integer) : real;
                                     ;   Parameter:  a = Vorkomma-Teil, b = Nachkomma-Stellen
        push    bp 
        mov     bp, sp 
        sub     sp, 0x40             ; 64 Bytes of lokalen Stack-Space
        mov     ax, [bp+8]           ; Erster Parameter der Funktion (Vorkomma-Teil)
        mov     bx, [bp+6]           ; Zweiter Parameter der Funktion (Nachkomma-Stellen)
       
        fninit                       ; Initialisiere FPU  ohne Vorab-Prüfung
        push    bx                   ; Nachkomma-Teil in BX auf Stack schieben ...
      ; fild    word sp              ; ... und weiter vom Stack auf ST(0) der FPU
      ; mov     cx, 1000             ; Bringe Divisor 1000 in CX
        fidiv   word [bp+8]          ; ... dividiere mit 1000 und bringe Ergebnis als Realzahl nach TOS
 
        push    ax                   ; Vorkomma-Teil von AX auf Stack schieben ...
        fild    word [bp+8]          ; ... und weiter vom Stack auf ST(0) der FPU
        fadd    st1                  ; Addiere ST(0) + ST(1) => ST(0)
       
        add     sp, 2                ; Stack um 2 Bytes wieder bereinigen (Ersatz für POP BX)
        add     sp, 2                ; Stack um 2 Bytes wieder bereinigen (Ersatz für POP AX)
       
    ; Gebe Ergebnis zurück in DX:BX:AX :  / Get Result in DX:BX:AX
      ; Veralteter Code   
      ; fstp    qword [erg8]         ; Speichere TOS (als Real-Zahl) in Ergebnis-Feld 'erg8' mit POP
      ; fninit                       ; Initialisiere FPU, aber ohne Vorab-Prüfung
      ; fstp    qword [ ]            ; Speichere an der durch     Error: Expression Syntax Error 
     
    ; Mal testweise:   / Only for Testing
    ; Voriger Ablauf unwichtig, schreibe Werte in AX:BX:DX:
    ; Gebe immer  1000,12345  aus!  ; (* Gibt in TEST111.PAS func_a() immer  3.1308...E0005 aus ...
      ; mov     cx, a
        mov     dx, 008Ah
        mov     bx,    0h
        mov     ax, 7A00h
         
        mov     sp,bp                ; undo "sub sp,0x40" above
        pop     bp
        retf    4      ; ret         ; Zurück zum Aufruf mit der Parameter-Größe von 4 Bytes
       
      end                            ; of ASM-Code
   
  ; ende nasm-Code 
 
 
; ende int_fpu.asn


Sorry, all Comments are in German - not in English.
But I think you can understand the Code also.
In weighty case you can make answer that I could translate them in Englisch.

I want to get back from the function any Results of Type real
(and other floating-point-Types like  Single, Double, Extended, Comp).
which is not described in any Places.
Which should be get back the Function-Result in DX:BX:AX


I do assemble the Code with
  nasm  -f obj  int_fpu.asn 
  (*.asn is my Variant for Assembler-Programs and Code
  instead of *.asm with TP/INTEL/MASM-Syntax) 
I also try with   -f bin  and/or together with  -o int_fpu.obj 
and sometimes I had try it with  -t

Then I include in TP7 with

  var
    a : real;
   
  {$L int_fpu.obj}
 
  function  Int2Real(a : integer; b : integer) : real;  external;
 
  begin
  a := Int2Real(1000,12345);
 
  writeln(' a = ', a);
 
 end. (* of program *)
 

But if I want to compile this Code in TP7
i always get the Error "Error 51: Invalid PUBLIC-Definition"
(after a Lot of other Errors/Problems wich I could have solved).

What does I doing wrong ?

I doesn't find any Hints/Tipps of this Problem in your Description.

Which is the correct Object-Format which should I used ?
If I try '- o bin' I can't use the 'EXTERN' or 'GLOBAL' statement.


I work in the NTVDM of WINDOWS 2000,
but I doesn't assume that this has any Influence it.

Could you get me some Help ?

And a Question more:  Where is the Macro-File  c16.mac  ?
Is this included in the nasm-Program ?
And which Makros are placed in it ?  Where can i find it?
And is the Statement  %define pascal  necessary for me ?

Any Help are I am pleasure and welcome.

Thank you beforehand

Sincerely

Günther Wenzl,
Germany

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Question Problem with "global"
« Reply #1 on: March 16, 2016, 07:24:36 PM »
Hi Günther,

Welcome to the Forum!

I speak no german. I "took" German in college but it was Tuesday-Thursday-Saturday at 8:00 in the cow-milking morning. I speak no German.

But code is code!

First, "c16.mac" is in the "misc" directory of the Nasm source code. I don't think it's what you want, but it's short...
Code: [Select]
; NASM macro set to make interfacing to 16-bit programs easier -*- nasm -*-



%imacro proc 1 ; begin a procedure definition

%push proc

  global %1

%1:   push bp

  mov bp,sp

%ifdef FARCODE PASCAL ; arguments may start at bp+4 or bp+6

%assign %$arg 6

%define %$firstarg 6

%else

%assign %$arg 4

%define %$firstarg 4

%endif

%define %$procname %1

%endmacro



%imacro arg 0-1 2 ; used with the argument name as a label

%00   equ %$arg

; we could possibly be adding some

; debug information at this point...?

%assign %$arg %1+%$arg

%endmacro



%imacro endproc 0

%ifnctx proc

%error Mismatched `endproc'/`proc'

%else

          mov sp,bp

          pop bp

%ifdef PASCAL

          retf %$arg - %$firstarg

%elifdef FARCODE

  retf

%else

  retn

%endif

__end_%$procname: ; useful for calculating function size

%pop

%endif

%endmacro
It would work, but I think you're better off without it.

"-f obj" is the output format you want. "-f bin" will give you a flat binary file. You can change the name with the "-o" switch, but it's still a flat binary file. "-f obj" is "OMF" - Object Module Format - which is what Pascal uses, I think.

I get a little confused about here:
Code: [Select]
      ; fild    word sp              ; ... und weiter vom Stack auf ST(0) der FPU
      ; mov     cx, 1000             ; Bringe Divisor 1000 in CX
        fidiv   word [bp+8]          ; ... dividiere mit 1000 und bringe Ergebnis als Realzahl nach TOS
 
        push    ax                   ; Vorkomma-Teil von AX auf Stack schieben ...
        fild    word [bp+8]          ; ... und weiter vom Stack auf ST(0) der FPU
        fadd    st1                  ; Addiere ST(0) + ST(1) => ST(0)

Commented out, but "sp", even "[sp]" isn't going to work in 16-bit code. You'll have to reference the stack from [bp]... which you do, but you seem to use "fidiv" without having loaded anything, then "fild" and "fadd". Which do you want to do?

I think that if you tell Pascal that the function returns "real", it will expect the result in st0. You want the result in DX:BX:AX? That may be a problem, I'm not sure. Doesn't Pascal expect callee to preserve BX? Might DX:CX:AX be better? In any case, I count 48 bits there. "double" wants 64 bits, and "extended" wants 80 bits. Is that going to be a problem?

You say:
Code: [Select]
  SEGMENT code private align=16
Do you want "private"? It may help to add "class=CODE" (I think that wants to be uppercase?)
Code: [Select]
segment code public align=16 class=CODE
?
"public" is default, so we shouldn't need to say it... I think "private" may be a mistake.

We probably haven't solved your problem yet, but perhaps I've made it more clear what I'm confused about and we can discuss it more. Sorry about my lack of German.

Best,
Frank