I am porting some .asm code from its old assembler MASM 5.0 to the newest MASM 6.15....as usual, I ran into problems:

the following error is generated:

1)
EXTERN macro name,xxx

returns error saying syntax error: macro
this error goes away when I make change to EXTERN, just use anything
other than it (e.g. EXTERN_) it will work...is EXTERN some kind of
preservered keyword or something??

2) LINK time error:
Assembling: io.asm
c.ah(351) : error A2214: GROUP directive not allowed with /coff option
NMAKE : fatal error U1077: 'C:\PROGRA~1\MICROS~2\VC98\BIN\ml.exe' :
return code
'0x1'
Stop.

I must compile it using /coff because even if I don't, when it links, it
tries to convert it to /coff anyway, which will return a related
error....

I am pretty new to MASM (actually I was porting a whole lot of win16 C
codes then all of a sudden this .asm file appear out of nowhere...)...so
please help!!!

The 2nd problem is what's really bugging me right now....so please help!!!
Posted on 2001-08-21 15:36:08 by mathfeel
With a few variations,

drv:\path\ml /c /coff yourfile.asm

is the correct syntax for 32 bit MASM files with ML.EXE.

drv:\path\Link /SUBSYSTEM:WINDOWS yourfile.obj your resourcefile.obj

The second obj module can be a RES file instead of an obj file converted by CVTRES.EXE.

Porting 16 bit C to 32 bit MASM is not going to be any real joy, you have both different OS architecture and a format of ASM file produced by VC that does not build directly in MASM.

If you have MASM32, have a look at the library format to see how it works, 32 bit assembler does not use SEGMENT definitions, just .model FLAT STDCALL.

Regards,

hutch@pbq.com.au
Posted on 2001-08-21 20:08:37 by hutch--
The default calling convention for 32-bit C/C++ is CDECL, where the caller cleans up the stack. The .h files use the C macro WINAPI to force STDCALL calling convention for API functions. Callbacks use the C macro CALLBACK to force STDCALL convention.

EXTERN is the new name of EXTRN.

GROUP is unnecessary in Win32.

If the asm file has instructions containing address registers, you will need to rewrite the MASM code.
    ; address registers are in []

mov cx,[di]
mov ax,[bx+si]
add ax,[bx]
Eliminate all loads and stores of segment registers.

Since the file is called IO.ASM, you might be able to use IN and OUT under Win 9x/ME. Depends on the ports used. You will need a driver to use ports under Win NT/2k/XP. If the file uses INT to do I/O, you will need to rewrite the MASM code.
Posted on 2001-08-21 21:05:56 by tank
hutch, porting (properly written) 16-bit C to win32asm will be easier
than porting 16bit applications to win32, simply because there haven't
been extremely major changes to the underlying API. Too bad that
there is long between "properly" written C applications :).

Anyway, if you're porting 16 bit C -> win32asm, do NOT start by
producing a 16bit asm file, and try to translate that to win32asm.
It will be a very very very tedious task. You will be dealing with
understanding compiler optimzations, *and* hand-translating
long sequences of 16bit code to 32bit. Better attack it in smaller
bits... look at a C function, figure out what it does, write the same
(from scratch) in 32bit asm. Sorry, but it's the only proper way to do
it. Which should also stop you from doing it unless there is a darned
good reason :).
Posted on 2001-08-21 22:00:04 by f0dder
mathfeel,

search the GROUP statements in you file and at let's have a look at them. Maybe it is a implicite GROUP statement like DOSSEG, so look for this string too.

japheth
Posted on 2001-08-22 03:04:53 by japheth
well...I am not exactly porting 16-bit C to 32-bit asm...
I have source code for a certain program that has both 16-bit C and 16-bit asm...I am just trying to make it work (C and asm under a 32-bit compiler/assember)....

I think I understand that GROUP is unnecessary in win32, but the problem is I can't just remove the group statement (tried to comment it out...all hell break lose)...if it helps, I am posting the code here. The GROUP statement are at toward the end of the CODE...but the GROUP that it defined, DGROUP, is referred many places inside the code...SO, TELL ME, HOW CAN I REMOVE ALL THE GROUP STATEMENTS SO THAT IT ASSEMBLES! I don't know how to mess with it because I am not very familiar with MASM (GOD, AFTER THIS I AM GOING TO WORK ON THAT!!):

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
C.AH starts here:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; macros and defines for C86PLUS assembly language code
; Copyright (C) 1986 Computer Innovations, Inc, ALL RIGHTS RESERVED

TRUE equ 1
FALSE equ 0

; ifndef BOOT_STRAP
BOOT_STRAP equ FALSE
; endif

; decode the cpu type information
; format is: CPU_[0123][7]


SET_CPU macro cpu,ndp,setcpu,setndp
ifdef CPU_&cpu&ndp
CPU_TYPE = cpu
ifidn <ndp>,<7>
NDP_TYPE = cpu
else
NDP_TYPE = 0
endif
setcpu
setndp
endif
endm

SET_CPU 0,7,.8086,.8087
SET_CPU 1,7,.186,.8087
SET_CPU 2,7,.286c,.287
SET_CPU 3,7,.286c,.287
SET_CPU 0,< >,.8086,.8087
SET_CPU 1,< >,.186,.8087
SET_CPU 2,< >,.286c,.287
SET_CPU 3,< >,.286c,.287


; decode the memory model information

ifdef SMALL_
FAR_DATA EQU FALSE
FAR_CODE EQU FALSE
endif

ifdef MEDIUM_
FAR_DATA EQU FALSE
FAR_CODE EQU TRUE
endif

ifdef LARGE_
FAR_DATA EQU TRUE
FAR_CODE EQU TRUE
endif

; set the defaults if needed

ifndef FAR_CODE
FAR_CODE equ FALSE
endif

ifndef FAR_DATA
FAR_DATA equ FALSE
endif

ifndef SET_SSDS
SET_SSDS equ TRUE
endif

ifndef SET_DS
SET_DS equ FALSE
endif

ifndef USCORE
UNDERSCORE equ FALSE
else
UNDERSCORE equ TRUE
endif

;EXTERN macro name, xxx
EXTRN_ macro name,xxx
ifidn <xxx>,<cp>
if FAR_CODE eq TRUE
if UNDERSCORE eq TRUE
extrn _&name:far
else
extrn name:far
endif
else
if UNDERSCORE eq TRUE
extrn _&name:near
else
extrn name:near
endif
endif
else
ifidn <xxx>,<dp>
if FAR_DATA eq TRUE
if UNDERSCORE eq TRUE
extrn _&name:dword
else
extrn name:dword
endif
else
if UNDERSCORE eq TRUE
extrn _&name:word
else
extrn name:word
endif
endif
else
if UNDERSCORE eq TRUE
extrn _&name:xxx
else
extrn name:xxx
endif
endif
endif
endm

GOSUB macro name
if UNDERSCORE EQ TRUE
if FAR_CODE EQ TRUE
call far ptr _&name
else
call near ptr _&name
endif
else
if FAR_CODE EQ TRUE
call far ptr name
else
call near ptr name
endif
endif
endm


FUN_PROC macro name
if UNDERSCORE EQ TRUE
public _&name
else
public name
endif
if FAR_CODE eq TRUE
if UNDERSCORE EQ TRUE
_&name PROC far
else
name PROC far
endif
ARG_BASE = 6
ARG_OFF = 6
AUTO_OFF = 0
else
if UNDERSCORE EQ TRUE
_&name PROC near
else
name PROC near
endif
ARG_BASE = 4
ARG_OFF = 4
AUTO_OFF = 0
endif
endm

FUN_BEG macro name,locals,regs
if UNDERSCORE EQ TRUE
_TEXT segment
assume cs:_TEXT,ds:DGROUP
else
@CODE segment
assume cs:@CODE,ds:DGROUP
endif
FUN_PROC name
enter locals,0
irp yy,<di,si,ds>
ifidn <yy>,<ds>
if SET_DS eq TRUE
assume ds:nothing
endif
endif
irp xx,<regs>
ifidn <xx>,<yy>
ifidn <xx>,<ds>
if SET_DS eq TRUE
assume ds:DGROUP
push ds
mov ax,DGROUP
mov ds,ax
endif
else
push xx
endif
endif
endm
endm
endm

FUN_LEAVE macro regs
irp yy,<ds,si,di>
irp xx,<regs>
ifidn <xx>,<yy>
ifidn <xx>,<ds>
if SET_DS eq TRUE
pop ds
endif
else
pop xx
endif
endif
endm
endm
leave
ret
endm

FUN_END macro name
if UNDERSCORE EQ TRUE
_&name endp
_TEXT ends
else
name endp
@CODE ends
endif
endm

FUN_AUTO macro name, siz
ifidn <siz>,<cp>
if FAR_CODE eq TRUE
AUTO_OFF = AUTO_OFF - 4
else
AUTO_OFF = AUTO_OFF - 2
endif
else
ifidn <siz>,<dp>
if FAR_DATA eq TRUE
AUTO_OFF = AUTO_OFF - 4
else
AUTO_OFF = AUTO_OFF - 2
endif
else
AUTO_OFF = AUTO_OFF - siz
endif
endif
if UNDERSCORE EQ TRUE
_&name = AUTO_OFF
else
name = AUTO_OFF
endif
endm

FUN_ARG macro name,siz
name = ARG_OFF
ifidn <siz>,<cp>
if FAR_CODE eq TRUE
ARG_OFF = ARG_OFF + 4
else
ARG_OFF = ARG_OFF + 2
endif
else
ifidn <siz>,<dp>
if FAR_DATA eq TRUE
ARG_OFF = ARG_OFF + 4
else
ARG_OFF = ARG_OFF + 2
endif
else
ARG_OFF = ARG_OFF + siz
endif
endif
endm

if CPU_TYPE eq 0
enter macro a,b
push bp
mov bp,sp
ifdif <a>,<0>
sub sp,a
endif
endm

leave macro
mov sp,bp
pop bp
endm

PUSHA MACRO
PUSH AX
PUSH CX
PUSH DX
PUSH BX
PUSH BX ;; Dummy value for SP
PUSH BP
PUSH SI
PUSH DI
ENDM

POPA MACRO
POP DI
POP SI
POP BP
POP BX ;; Dummy value for SP
POP BX
POP DX
POP CX
POP AX
ENDM
endif


; define basic segments

if UNDERSCORE EQ FALSE ; c86 compiler segment conventions
@CODE Segment Byte Public 'CODE'
@CODE EndS
@DATAB Segment PARA Public 'DATAB'
@DATAB EndS
@DATAC Segment Byte Public 'DATAC'
@sb label Byte
@sw label word
@DATAC EndS
@DATAI Segment Byte Public 'DATAI'
@ib label Byte
@iw label word
@DATAI EndS
@DATAT Segment Byte Public 'DATAT'
@DATAT EndS
@DATAU Segment Byte Public 'DATAU'
@ub label Byte
@uw label word
@DATAU EndS
@DATAV Segment Byte Public 'DATAV'
@DATAV EndS

DGroup Group @DATAB,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV

else ; c86plus and microsoft
_TEXT segment byte public 'CODE'
_TEXT ends
if BOOT_STRAP eq TRUE
C_ETEXT segment byte public 'ENDCODE'
C_ETEXT ends
endif
if BOOT_STRAP eq TRUE
if SET_SSDS eq FALSE
DGROUP group NULL,_DATA,_BSS,NEARHEAP,STACK
else
DGROUP group NULL,_DATA,_BSS,STACK
endif
else
DGROUP group NULL,_DATA,_BSS
endif

NULL segment para public 'BEGDATA'
assume ds:DGROUP
NULL ends
_DATA segment word public 'DATA'
assume ds:DGROUP
_DATA ends
_BSS segment word public 'BSS'
assume ds:DGROUP
_BSS ends
if BOOT_STRAP eq TRUE
if SET_SSDS eq FALSE
NEARHEAP segment para public 'BSS'
assume ds:DGROUP
NEARHEAP ends
endif
STACK segment para stack 'STACK'
STACK ends
endif

endif ; c86plus and microsoft

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
C.AH Ends here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

the line that I am compiling this with is:
ml /D "CPU_2" /D "LARGE" /D "USCORE" /Zi /c /coff IO.ASM
and linking:
lib /VERBOSE /MACHINE:IX86 /SUBSYSTEM:CONSOLE /OUT:\PATH\name.lib
Posted on 2001-08-22 15:39:30 by mathfeel
And just how much assembly code do you have?

If it's just one small .ASM file plus this assembly header file, you're better off rewriting it without the header file.

Take out the ASM file(s) and create a C file that replaces the missing functions (you can let the linker tell you what they are). Once you've got the C code compiling and linking, go back, make sense of the ASM code, and rewrite it! That's because the assembly header won't properly handle 32-bit code of any kind.

If the ASM code is large, there's a very good chance that it uses addressing modes which are invalid in Win32 code -- which means you can't avoid a major rewrite.
Posted on 2001-08-24 17:24:08 by tank