VOGONS


First post, by Exploit

User metadata
Rank Newbie
Rank
Newbie

I have three assembler files for DOS, these are:

MAIN.ASM
; Note:         Quit with CTRL+C
; Program name: MAIN.ASM

EXTRN WAIT_X:FAR
.MODEL SMALL
.STACK 256

.CODE
START:
MOV DL, 00h

M1:
MOV AH, 02h
INT 21h ; Shows value of DL register
INC DL
CALL WAIT_X ; subroutine call of WAIT_X
JMP M1
MOV AH, 4Ch ; return to DOS
INT 21h
END START
WAIT_A.ASM
; Note:         With manual register saving
; Program name: WAIT_A.ASM
PUBLIC WAIT_X
.MODEL SMALL
.STACK 256

.CODE
WAIT_X PROC FAR ; subroutine
PUSH BX
PUSH CX
MOV BL, 80H ; delay loop

M2: MOV CX, 0FFFFh ; outer loop
M1: DEC CX ; inner loop
JNZ M1
DEC BL
JNZ M2
POP CX
POP BX
RET ; return to main
WAIT_X ENDP

END

and

WAIT_B.ASM
; Note:         With USES directive and language type C
; Program name: WAIT_B.ASM
PUBLIC WAIT_X
.MODEL SMALL, C
.STACK 256

.CODE
WAIT_X PROC FAR USES BX CX ; subroutine
MOV BL, 80H ; delay loop

M2: MOV CX, 0FFFFh ; outer loop
M1: DEC CX ; inner loop
JNZ M1
DEC BL
JNZ M2
RET ; return to main
WAIT_X ENDP

END

WAIT_A.ASM and WAIT_B.ASM use both the same public routine name WAIT_X which is called by MAIN.ASM
The only difference is, that WAIT_B does make use of the USES assembler directive and this directive expects to have a language type set in the directive .MODEL

diff WAIT_A.ASM WAIT_B.ASM
diff WAIT_A.ASM WAIT_B.ASM 
1,2c1,2
< ; Note: With manual register saving
< ; Program name: WAIT_A.ASM
---
> ; Note: With USES directive and language type C
> ; Program name: WAIT_B.ASM
4c4
< .MODEL SMALL
---
> .MODEL SMALL, C
8,10c8
< WAIT_X PROC FAR ; subroutine
< PUSH BX
< PUSH CX
---
> WAIT_X PROC FAR USES BX CX ; subroutine
18,19d15
< POP CX
< POP BX

When i use the following comands:

jwasmr -0 MAIN.ASM WAIT_A.ASM WAIT_B.ASM  
wlink name main_a file main,wait_a
wlink name main_b file main,wait_b

The assembly of the files works without erros:

JWasm v2.14, Dec 20 2020, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

MAIN.ASM: 20 lines, 2 passes, 0 ms, 0 warnings, 0 errors
WAIT_A.ASM: 23 lines, 2 passes, 0 ms, 0 warnings, 0 errors
WAIT_B.ASM: 19 lines, 2 passes, 0 ms, 0 warnings, 0 errors

And wlink works with the WAIT_A.OBJ file but it fails with the similar but not identical WAIT_B.OBJ file.
It gives the following error message when using WAIT_B.OBJ:

Error! E2028: WAIT_X is an undefined reference
creating a DOS executable
file main.obj(MAIN.ASM): undefined symbol WAIT_X

Can anyone tell me how to fix this and why this error occurs?

Both WAIT* files use the PUBLIC directive to make the WAIT_X function public.
And MAIN.ASM has a EXTRN WAIT_X:FAR directive, thus it should know that WAIT_X function.
But still, it fails.

Personally i assume, that the set language type C in the .MODEL directive is the problem. At least the same error will occur, if i set the same language type in WAIT_A.ASM to C.
But i don't know, how to solve that.

I also tried other language types, like FASTCALL
.MAIN SMALL, FASTCALL
but this didn't solve it.

Reply 1 of 4, by vstrakh

User metadata
Rank Member
Rank
Member

I don't have experience with JWasm, but with TASM declaring model's language affects the generated names of the procedures, the C language implicitly adds underscore in front of the function, so it's important that the calling side knows that - either being also compiled as C model, or explicitly specifying the underscore when calling C procedure, e.g. 'call _WAIT_X'

It's also possible to use C calling conventions without declaring the whole module as C model.
Just remove the ", C" in the model definition, and add language specifier directly to the procedure.
E.g.:

WAIT_X PROC C FAR USES BX CX

This way there will be no implicitly generated underscore in the procedure name.
At least that would be the approach with TASM, but may work with JWasm if it follows MASM rules close enough.

Reply 2 of 4, by Exploit

User metadata
Rank Newbie
Rank
Newbie
vstrakh wrote on 2022-10-13, 14:51:

I don't have experience with JWasm, but with TASM declaring model's language affects the generated names of the procedures, the C language implicitly adds underscore in front of the function, so it's important that the calling side knows that - either being also compiled as C model, or explicitly specifying the underscore when calling C procedure, e.g. 'call _WAIT_X'

Thanks a lot! That was the error.

I tried to add an underscore before, but my mistake was, that i added them in all files.
The solution is to add the underscore only in the calling procedure.
In this case, only in MAIN.ASM not in WAIT_A.ASM and not in WAIT_B.ASM

It's also possible to use C calling conventions without declaring the whole module as C model. […]
Show full quote

It's also possible to use C calling conventions without declaring the whole module as C model.

Just remove the ", C" in the model definition, and add language specifier directly to the procedure.
E.g.:

WAIT_X PROC C FAR USES BX CX

Thank you for the hint, that worked too.
But i had to change the order of FAR and C to:

WAIT_X PROC FAR C USES BX CX

otherwise i got an ERROR when FAR was after C.

This way there will be no implicitly generated underscore in the procedure name.
At least that would be the approach with TASM, but may work with JWasm if it follows MASM rules close enough.

I tested this now. JWASM still implicitly generates an underscore in the procedure name. It doesn't matter where the C language definition is defined, in model or proc.

Thus it is a must to add an additional leading underscore in all calling procedures.

Reply 3 of 4, by Exploit

User metadata
Rank Newbie
Rank
Newbie

BTW if you want mix *.ASM and *.C code then keep in mind the following:

In the ASM code the underscore must be appended at the end of the function name without an underscore at the front. myfunc_
In the C code the underscore must be appended in front of the function name without an underscore at the end. _myfunc

Example *.ASM file:

.MODEL SMALL, C   ; the C option will tell JWASM to append an underscore at front of each public function automatically
...
public myfunc_
...
.CODE
myfunc_ PROC
....
myfunc_ ENDP
...

Example *.C file

EXTERN VOID _myfunc()  // No underscore at the end, only at the front
...
void main(){
...
_myfunc(); // No underscore at the end, only at the front
...
}

The C compiler automatically adds an underscore at the end of the external function in the OBJ File, that's why the function must have an underscore at the end in the ASM file.
You can see that with Open Watcom's DMPOBJ command.

Don't ask me why it's so weird implemented and messed up in Open Watcom. But if you don't do it that way, WLINK will complain with an undefined reference message for this example function.

This was tested with:
JWASM version 2.14
WLINK version 1.9
WCC version 1.9

Reply 4 of 4, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie
Exploit wrote on 2023-11-17, 16:18:

In the ASM code the underscore must be appended at the end of the function name without an underscore at the front. myfunc_
In the C code the underscore must be appended in front of the function name without an underscore at the end. _myfunc

this is not entirely correct. it depends on the compilers calling convention, or the calling convention declared on the function, if you compile with cdecl, it prepends, with watcom calling convention it appends it, and with fastcall I think there is none. (and the calling convention changes how the arguments are passed and who is responsible for removing them on return,
so just because syscall + fastcall show without underscores, they both do different things with arguments and removing arguments on return!)

cdecl = _func
stdcall = _func
pascal = FUNC
fastcall = func
syscall = func
watcom = func_

Exploit wrote on 2023-11-17, 16:18:

Don't ask me why it's so weird implemented and messed up in Open Watcom

Its not messed up, you just dont understand conventions and why things are the way they are. There are technical debt reasons from different compilers (microsoft/zortech/symantic/digital mars/watcom/etc)

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--