News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Macro help

Started by cozofdeath, June 11, 2012, 03:48:41 AM

Previous topic - Next topic

cozofdeath

I've successfully integrated the zlib library/headers into my project however their is a set of macros left yet to convert to usable MASM code. I was wondering if maybe someone could help me out. Below are two of the five that have been converted from C code to Masm but don't work.

deflateInit MACRO strm,level
EXITM <deflateInit_ ( ( strm ) , ( level ) , ZLIB_VERSION , sizez_stream ) >
ENDM

inflateInit MACRO strm
EXITM <inflateInit_,strm, ZLIB_VERSION, z_stream>
ENDM


They were converted from their C counter parts below ...

#define deflateInit(strm, level) \
        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))

#define inflateInit(strm) \
        inflateInit_((strm),ZLIB_VERSION, sizeof(z_stream))


Thanks for any help.

qWord

if deflateInit_ is a function, then it could be:

deflateInit MACRO strm,level
EXITM rv(deflateInit_ , strm , level , ZLIB_VERSION , sizez_stream )
ENDM

rv() is a macro, which can be found in macros.asm (MASM32 SDK).

If deflateInit is a macro, then remove the angle brackets from the call
MREAL macros - when you need floating point arithmetic while assembling!

Greenhorn

Quote from: cozofdeath on June 11, 2012, 03:48:41 AM
I've successfully integrated the zlib library/headers into my project however their is a set of macros left yet to convert to usable MASM code. I was wondering if maybe someone could help me out. Below are two of the five that have been converted from C code to Masm but don't work.

They should work in this way:
invoke deflateInit(firstArg, secondArg)

invoke inflateInit(Arg)
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

cozofdeath

Thanks qWord for the macro. I do have the macros.asm file included and I've tried the rv, rvc, and fnc macros from it but all result in errors. I've tried every combination of things I would think would work and I always get an error. deflateInit_ is a C style function. I can call it fine outside this macro with all of it's arguments but in the macro it always fails. Your idea makes sense but it still won't compile.

Thanks Greenhorn for the comment. I don't think you can invoke a macro can you? When it didn't work that was what I figured but I'm not a MASM expert just a beginner. Again thanks guys for the comments. Any more ideas or should I just abandon these "easier to use" macros zlib has lol.

MichaelW

Instead of leaving us to guess at what the problems might be from vague descriptions and small snippets of code, try posting the relevant parts of your assembly code, along with the relevant parts of the translated header files.
Well Microsoft, here's another nice mess you've gotten us into.

cozofdeath

Ok, I'll try to post some more info.

To just focus on the inflateInit macros and its relevant code here is the inflateInit_ prototype that the inflateInit macro uses.
inflateInit_ PROTO C :z_stream, :DWORD, :DWORD

Here is the z_stream structure:
z_stream STRUCT
next_in DWORD ? /* next input byte */
avail_in DWORD ?        /* number of bytes available at next_in */
total_in DWORD ?        /* total nb of input bytes read so far */
next_out DWORD ?       /* next output byte should be put there */
avail_out DWORD ?       /* remaining free space at next_out */
total_out DWORD ?        /* total nb of bytes output so far */
msg DWORD ? /* last error message, NULL IF no error */
state internal_state <>        /* not visible by applications */
zalloc DWORD ? /* used to allocate the internal state */
zfree DWORD ? /* used to free the internal state */
opaque DWORD ? /* private data object passed to zalloc and zfree */
data_type DWORD ? /* best guess about the data type: ascii or binary */
adler DWORD ? /* adler32 value of the uncompressed data */
reserved DWORD ? /* reserved for future use */
z_stream ENDS


Here is the defined ZLIB_VERSION   constant.
ZLIB_VERSION EQU <"1.2.1">


That's really all there is other than calling the macro. It's just an initialization macro so it doesn't really need any data. It just uses the structure passed for values the actual worker functions will fill and it checks the version to make sure its the correct library and then the size of the structure. Here are both the header files that I'm working with. I'm sure there are more issues as I've yet to really get into using them.

This is zlib.inc:
INCLUDE zconf.inc
INCLUDE macros.asm


; ##################### TYPEDEFS ###################
z_streamp TYPEDEF ptr z_stream


; ##################### STRUCTURES ###################
internal_state STRUCT
dummy DWORD ?
internal_state ends

z_stream STRUCT
next_in DWORD ? /* next input byte */
avail_in DWORD ? /* number of bytes available at next_in */
total_in DWORD ? /* total nb of input bytes read so far */
next_out DWORD ? /* next output byte should be put there */
avail_out DWORD ? /* remaining free space at next_out */
total_out DWORD ? /* total nb of bytes output so far */
msg DWORD ? ;26060496 /* last error message, NULL IF no error */
state internal_state <> /* not visible by applications */
zalloc DWORD ? /* used to allocate the internal state */
zfree DWORD ? /* used to free the internal state */
opaque DWORD ? /* private data object passed to zalloc and zfree */
data_type DWORD ? /* best guess about the data type: ascii or binary */
adler DWORD ? /* adler32 value of the uncompressed data */
reserved DWORD ? /* reserved for future use */
z_stream ENDS

; ##################### PROTOTYPES ###################
zlibVersion PROTO C
deflate PROTO C :z_streamp, :DWORD
deflateEnd PROTO C :z_streamp
inflate PROTO C :z_streamp, :DWORD
inflateEnd PROTO C :z_streamp
deflateSetDictionary PROTO C :z_streamp, :DWORD, :DWORD
deflateCopy PROTO C :z_streamp, :z_streamp
deflateReset PROTO C :z_streamp
deflateParams PROTO C :z_streamp, :DWORD, :DWORD
deflateBound PROTO C :z_streamp, :DWORD
deflatePrime PROTO C :z_streamp, :DWORD, :DWORD
inflateSetDictionary PROTO C :z_streamp, :DWORD, :DWORD
inflateSync PROTO C :z_streamp
inflateCopy PROTO C :z_streamp, :z_streamp
inflateReset PROTO C :z_streamp
inflateBack PROTO C :z_streamp, :DWORD, :DWORD, :DWORD, :DWORD
inflateBackEnd PROTO C :z_streamp
zlibCompileFlags PROTO C
compress PROTO C :DWORD, :DWORD, :DWORD, :DWORD
compress2 PROTO C :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
compressBound PROTO C :DWORD
uncompress PROTO C :DWORD, :DWORD, :DWORD, :DWORD
gzopen PROTO C :DWORD, :DWORD
gzdopen PROTO C :DWORD, :DWORD
gzsetparams PROTO C :DWORD, :DWORD, :DWORD
gzread PROTO C :DWORD, :DWORD, :DWORD
gzwrite PROTO C :DWORD, :DWORD, :DWORD
gzprintf PROTO C :DWORD, :DWORD, :VARARG
gzputs PROTO C :DWORD, :DWORD
gzgets PROTO C :DWORD, :DWORD, :DWORD
gzputc PROTO C :DWORD, :DWORD
gzgetc PROTO C :DWORD
gzungetc PROTO C :DWORD, :DWORD
gzflush PROTO C :DWORD, :DWORD
gzseek PROTO C :DWORD, :DWORD, :DWORD
gzrewind PROTO C :DWORD
gztell PROTO C :DWORD
gzeof PROTO C :DWORD
gzclose PROTO C :DWORD
gzerror PROTO C :DWORD, :DWORD
gzclearerr PROTO C :DWORD
adler32 PROTO C :DWORD, :DWORD, :DWORD
crc32 PROTO C :DWORD, :DWORD, :DWORD
deflateInit_ PROTO C :z_streamp, :DWORD, :DWORD, :DWORD
inflateInit_ PROTO C :z_streamp, :DWORD, :DWORD
deflateInit2_ PROTO C :z_streamp, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
inflateInit2_ PROTO C :z_streamp, :DWORD, :DWORD, :DWORD
inflateBackInit_ PROTO C :z_streamp, :DWORD, :DWORD, :DWORD, :DWORD
zError PROTO C :DWORD
inflateSyncPoint PROTO C :z_streamp
get_crc_table PROTO C


; ##################### CONSTANTS ###################
ZLIB_VERSION EQU <"1.2.1">
ZLIB_VERNUM EQU 1210h
Z_NO_FLUSH EQU 0
Z_PARTIAL_FLUSH EQU 1
Z_SYNC_FLUSH EQU 2
Z_FULL_FLUSH EQU 3
Z_FINISH EQU 4
Z_BLOCK EQU 5
Z_OK EQU 0
Z_STREAM_END EQU 1
Z_NEED_DICT EQU 2
Z_ERRNO EQU -1
Z_STREAM_ERROR EQU -2
Z_DATA_ERROR EQU -3
Z_MEM_ERROR EQU -4
Z_BUF_ERROR EQU -5
Z_VERSION_ERROR EQU -6
Z_NO_COMPRESSION EQU 0
Z_BEST_SPEED EQU 1
Z_BEST_COMPRESSION EQU 9
Z_DEFAULT_COMPRESSION EQU -1
Z_FILTERED EQU 1
Z_HUFFMAN_ONLY EQU 2
Z_RLE EQU 3
Z_DEFAULT_STRATEGY EQU 0
Z_BINARY EQU 0
Z_ASCII EQU 1
Z_UNKNOWN EQU 2
Z_DEFLATED EQU 8
Z_NULL EQU 0


; ##################### MACROS ###################

deflateInit MACRO strm,level
EXITM <deflateInit_ ( ( strm ) , ( level ) , ZLIB_VERSION , sizez_stream ) >
ENDM

inflateInit MACRO strm
EXITM <fnc(inflateInit_, strm, SADD(ZLIB_VERSION), SIZEOF z_stream)>
ENDM

deflateInit2 MACRO strm,level,method,windowBits,memLevel,strategy
EXITM <deflateInit2_ ( ( strm ) , ( level ) , ( method ) , ( windowBits ) , ( memLevel ) , ( strategy ) , ZLIB_VERSION , sizez_stream ) >
ENDM

inflateInit2 MACRO strm,windowBits
EXITM <inflateInit2_ ( ( strm ) , ( windowBits ) , ZLIB_VERSION , sizez_stream ) >
ENDM

inflateBackInit MACRO strm,windowBits,window
EXITM <inflateBackInit_ ( ( strm ) , ( windowBits ) , ( window ) , ZLIB_VERSION , sizez_stream ) >
ENDM


This is zconf.inc:
IFDEF Z_PREFIX
deflateInit_ EQU <z_deflateInit_>
deflate_ EQU <z_deflate> ; This name conflicts with a masm32 keyword/label?
deflateEnd EQU <z_deflateEnd>
inflateInit_ EQU <z_inflateInit_>
inflate_ EQU <z_inflate>
inflateEnd EQU <z_inflateEnd>
deflateInit2_ EQU <z_deflateInit2_>
deflateSetDictionary EQU <z_deflateSetDictionary>
deflateCopy EQU <z_deflateCopy>
deflateReset EQU <z_deflateReset>
deflatePrime EQU <z_deflatePrime>
deflateParams EQU <z_deflateParams>
deflateBound EQU <z_deflateBound>
inflateInit2_ EQU <z_inflateInit2_>
inflateSetDictionary EQU <z_inflateSetDictionary>
inflateSync EQU <z_inflateSync>
inflateSyncPoint EQU <z_inflateSyncPoint>
inflateCopy EQU <z_inflateCopy>
inflateReset EQU <z_inflateReset>
compress EQU <z_compress>
compress2 EQU <z_compress2>
compressBound EQU <z_compressBound>
uncompress EQU <z_uncompress>
adler32 EQU <z_adler32>
crc32 EQU <z_crc32>
get_crc_table EQU <z_get_crc_table>
ENDIF

defined MACRO x
IFDEF x
  exitm <1>
else
  exitm <0>
ENDIF
endm


IF defined(_WINDOWS) AND  0 eq defined(WINDOWS)
WINDOWS EQU <>
ENDIF

IF (defined(_WIN32) OR defined(__WIN32__)) AND  0 eq defined(WIN32)
WIN32 EQU <>
ENDIF


IF defined(WINDOWS) OR defined(WIN32)
IFDEF ZLIB_DLL
IF defined(WIN32)
IFDEF ZLIB_INTERNAL
ZEXTERN EQU <extern __declspec ( dllexport )>
else
ZEXTERN EQU <extern __declspec ( dllimport )>
ENDIF
ENDIF
ENDIF
IFDEF ZLIB_WINAPI
ZEXPORT EQU <WINAPI>
IFDEF WIN32
ZEXPORTVA EQU <WINAPI>
ENDIF
ENDIF
ENDIF



IFNDEF ZEXTERN
ZEXTERN EQU <extern>
ENDIF

IFNDEF ZEXPORT
ZEXPORT EQU <>
ENDIF

IFNDEF ZEXPORTVA
ZEXPORTVA EQU <>
ENDIF



Here is Zlib.h (original c file with descriptions for everything)
http://www.pastie.org/4066938

Here is Zconf.h
http://www.pastie.org/4066948


Also, here is a rar I've made of the dll/lib/header files I'm using for zlib.
http://www.sendspace.com/file/v9tzm5
Thank you guys for any help and any constructive criticism will help.

Greenhorn

Your function declaration is wrong.
It must be:

inflateInit_          PROTO C :ptr z_stream, :DWORD, :DWORD

and then call it as I mentioned:

; declaration for your struct in code, e.g. in a local variable:
LOCAL zstr:z_stream

; call the function via macro
invoke inflateInit(addr zstr)
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

cozofdeath

Perfect Greenhorn! :t That was it. I didn't even know you could use a macro like that (or nest them like this) with invoke but hey it's working. The only question I have is why the ptr in the PROTO. In a debugger it does the same thing as not leaving it there so I'm guessing it's for type checking or something?

Greenhorn

Quote from: cozofdeath on June 12, 2012, 07:07:15 AM
I didn't even know you could use a macro like that (or nest them like this) with invoke but hey it's working.
This is because macros are expanded at first of all. If you take a look at your listing file (command line switch /Sg) you'll see the generated code.

Quote from: cozofdeath on June 12, 2012, 07:07:15 AMThe only question I have is why the ptr in the PROTO. In a debugger it does the same thing as not leaving it there so I'm guessing it's for type checking or something?
You could also write inflateInit_  PROTO C :DWORD, :DWORD, :DWORD but to keep it compatible with 64bit asm it's better to declare it in the other way. And yes, if your assembler supports type checking it's a little bit safer.
Another way were to declare the proto like this: inflateInit_  PROTO C :z_streamp, :DWORD, :DWORD because you made a typedef in your include file.
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.