News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Converting MASM611 programs to MASM3211

Started by MtheK, July 16, 2013, 02:12:38 PM

Previous topic - Next topic

MtheK

  I've been coding MASM programs since 1990, and IBM MainFrame ASM
since 1973. I recently converted all of my MASM programs from 16bit/
.MODEL SMALL/INT21h to 32bit/.MODEL FLAT/WIN32 API. For example:

http://users.foxvalley.net/~qcd/index4.htm

the DSNTODAY system, which can detect recently-implanted executables.

  First, I changed my source; mostly regs to Eregs and INT21h to
INVOKE. All went well, tho it took awhile. However, I did have to
.NOLIST all of the .inc's & give up XREFs, else my .LST file was
absurdly huge! Is there an SXREF, a la IBM; that is, only show the
label only if it's referenced?

  Next, I used the new linker. Again, all went well, tho I got
msgLNK4033/COFF.

  Finally, I used the new assembler. No source had to change here.
Tho all SEEMED to go well, I found that, when testing with WinDbg,
all of my labels in the .DATA section were no longer recognized by
the View/Memory window and I had to use hard addresses to see them.

  After trying a few things, I found that, if I added the "/coff"
operand to the new assembler, WinDbg was once again able to see my
labels by name.

  Is this a requirement of the new assembler? MASM611 worked fine.
I did not notice any warning messages anywhere indicating that my
labels would be lost. There doesn't seem to be any other issues;
all my programs run as expected. The .exe sizes are about the same.
Are there any ramifications when using this? Are there any other
significant items I should know/consider when converting? I converted
because I'm not sure if MASM611 would function on Win8 if 16bit is
eliminated, and I'm not about to lose all of my programs if true!

hutch--

A few things, all 32 bit Windows executables are COFF object modules so this is the correct setting for 32 bit. If you can get the swing of it, the 32 bit instructions can do more and a lot faster than the earlier 16 bit versions so it may be worth rewriting bits and pieces to get your speed up. Another factor is the amount of memory you can routinely use, with 16 bit you had the addressing range limit of a nominal 640k where you can routinely use megabytes of memory in 32 bit and not tax the system.

The Windows API functions are effectively the modern equivalents of the older 16 bit DOS/BIOS interrupts, its just that they will do far more than can be done under DOS. They can look a bit daunting at first but once you get used to the naming conventions they usually make sense. The main irritation that programmers migrating from DOS have is the interface API functions and while they are no joy to have to learn, the capacity increase is worth the effort as you can do a massive number of useful things with the API GUI interface.

jj2007

Hi MtheK,

First of all, welcome in the Forum :icon14:

Adding to what Hutch already wrote, here a standard snippet using the Masm32 library:

include \masm32\include\masm32rt.inc

.code
AppName   db "Masm32:", 0

MyTest proc argTitle
LOCAL v1, rc:RECT
  and v1, 0
  mov rc.top, 12345h
  MsgBox 0, str$(rc.top), argTitle, MB_YESNO
  ret
MyTest endp

start:   invoke MyTest, offset AppName
   exit eax

end start


Nothing new for you, I guess, since you have already converted most of your 16-bit code to the Win32 world. Now, to get symbols working, you need the right assembler, the right linker, and the right commandline options. That sounds trivial, but some combinations simply don't work.

This does work:
Assembler commandline options:   /c /coff
Linker commandline options:   /debug


... provided you use:
1. either MASM 6.15 or JWasm (highly recommended)
2. polink (slow with symbols) or MS link version 6.14 (as supplied with the Masm32 package)

The combination JWasm plus link is really fast, and works perfectly. Many of us here use Olly for debugging, it's worth a try, but I guess you'll stick to what you are already familiar with ;-)

With Olly version 1.1, you'll see the snippet above as follows:
AppName    .  4D 61 73 6D 3>ascii "Masm32:",0
MyTest    /$  55            push ebp
00401019  |.  8BEC          mov ebp, esp
0040101B  |.  83C4 EC       add esp, -14
0040101E  |.  8365 FC 00    and [local.v1], 0
00401022  |.  C745 F0 45230>mov [local.rc+4], 12345
00401029  |.  68 00404000   push offset ??0019
0040102E  |.  FF75 F0       push [local.rc+4]
00401031  |.  E8 3A000000   call dwtoa
00401036  |.  6A 04         push 4                                   ; /Style = MB_YESNO|MB_APPLMODAL
00401038  |.  FF75 08       push [arg.argTitle]                      ; |Title = ""
0040103B  |.  68 00404000   push offset ??0019                       ; |Text = ""
00401040  |.  6A 00         push 0                                   ; |hOwner = NULL
00401042  |.  E8 8F000000   call MessageBoxA                         ; \MessageBoxA
00401047  |.  C9            leave
00401048  \.  C2 0400       retn 4
<ModuleEn>/$  68 10104000   push AppName                             ; ASCII "Masm32:"
00401050  |.  E8 C3FFFFFF   call MyTest                              ; \MyTest
00401055  |.  50            push eax                                 ; /ExitCode = 7633ED5A
00401056  \.  E8 81000000   call ExitProcess                         ; \ExitProcess


Re huge .LST files: Have you tried to list only the code after the includes?
.nolist
include whatever.inc
...
.listall
... data & code ...

Gunther

You have to know the facts before you can distort them.

MtheK

  Thank you all for your comments. I'm glad that /coff won't cause any problems.
I do see that the API has more features; for example, SLEEP, which, at least for
me, I could never find in 16bit.

  I do indeed use "/c /coff" with "/Zi /Sn /Fl" in ML and "/DEBUG /MAP" in LINK,
which seems to work properly for me.

  I tried OllyDebug a while ago; it looked interesting. Does it work with source?
This technique seems similar to XPED in IBM-land. I also notice that, when working
with crash/snap dumps, !analyze -v will pinpoint the line of source code where the
PSW (ie: CS:IP) points to; very cool.

  For .LST; I do indeed wrap the .inc's w/.NOLIST and .LIST so I can get the
object code listing. Doing this, they are only a few hundred K or so;
very manageable and WAY better than 8M. The lack of an "SXREF" is annoying
at times, but using FIND in NOTEPAD usually works for me.

  FYI: I also have to delete the .pdb B 4 the LINK, else DUMPPE complains about
the timestamp. I assume this has something to do with an INCREMENTAL link?
It doesn't affect my execution or my debugging either way; I usually always
start fresh, copying in the source, then move the files back to my own DIR.

jj2007

Quote from: MtheK on July 16, 2013, 10:30:13 PM
I tried OllyDebug a while ago; it looked interesting. Does it work with source?

Yes, although I hardly use it - the symbols are usually clear enough. To open the source window, select the line with the file name, then right-click as shown below.

Olly is very easy to use; just insert an INT 3 where you need it, hit F9 to go there, and proceed with F8 (or F7 if you want to enter a proc; to leave it quickly, press Ctrl F9).

MtheK

  Funny u mention INT3; perhaps u can explain why I can no longer use it in my 32bit w/o crashing. It's 1 of the things I seem to have lost (or, at least, dynamically run when actually needed & tolerate the crash) from 16bit:

http://windowssecrets.com/forums/showthread.php/151816-Win7-32bitAPI-ExitThread-ExitProcess-crash-2147483645-7FFFFFFDh-w-INT3?p=889007#post889007

jj2007

int 3 throws an exception in Win32. It's only significant use is... debugging. Put an int 3 in front of the loop of interest, press F9 to let Olly jump to it, and start watching.

But of course, if you want to run the program in normal, non-debugging mode, you need to comment out the int 3, otherwise it will crash.

MtheK

  HAH! I JUST NOW realized that I can turn this dis-advantage into an advantage.
In 16bit, I could never figure out a way to cause a deliberate crash (ie: S0C1),
thus creating a dump, which I could then analyze w/the source, such as in
situations when WinDbg seems N/A (or perhaps harder?), such as in a WTS SERVICE, or during a PowerOff. But, NOW I CAN! When my logic detects something un-usual, I do an 'INT 3', and, there's my dump. DUH!

dedndave

INT 3 is unique, in that it is a single-byte opcode (other INT's are 2 bytes) - it's know as the "trap" or "single-step" interrupt
some assemblers even allow "INT3" (no space) as a special mnemonic
this allows it to be used to temporarily replace other single (or multiple) byte opcodes

the old DOS DEBUG didn't have breakpoints, but you could insert INT 3 and create one
SYMDEB, a later version of DEBUG, would set up breakpoints for you by inserting an INT 3