NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: Guenni60 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
-
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...
; 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:
; 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:
SEGMENT code private align=16
Do you want "private"? It may help to add "class=CODE" (I think that wants to be uppercase?)
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