Can MASM32 produce COM files. I'm a Visual Basic programmer and am new to assembler. I have an example Visual Basic program with a very small machine code program embedded in a string constant. The Hex string data is loaded into byte array and executed using the CallWindowProc api call.

An example assembly file is included that produces a 14 byte com file.

This is the Com file from MASM Open binary Hext command
---------------------------------------------------------------------------
; C:\Applications\Desktop\MASM32\MachCd\TEST.COM 14 bytes

00000000: 55 89 E5 B8 4E 61 BC 00 - 89 EC 5D C2 10 00


This is the asm file that produced the above com file.
---------------------------------------------------------------------------
;Test.asm
;eax goes into result& of CallWindowProc
USE32
push ebp
mov ebp,esp

mov eax,12345678

mov esp,ebp
pop ebp
ret 16


I have tried to modify it to work with MASM as follows:
---------------------------------------------------------------------------
.386
.model small
.code

push ebp
mov ebp,esp

mov eax,12345678

mov esp,ebp
pop ebp
ret 16
END



I've tried the following batch file to try and create the Com file without success.
---------------------------------------------------------------------------
\masm32\bin\ml /AT /c /FlMList.txt Test1.asm

It assembles, but wont link. Is this my main problem or does MASM32 not produce small files without the file headers on them?

I know I may not be asking the right questions, but I'm new to assembler and all this is confusing to me.

Thanks - Jack Rasnick
rasnick@att.net
Posted on 2002-02-21 18:06:54 by JackRazz
Actually the MASM32 package contains the linker from the win98ddk but other Microsoft linker will work fine as long as you understand the file alignment switch and ignore the warning.

To produce a DOS memory image COM file, you need the old OMF linker which is available from either the Microsoft web site or if you cannot find it, get it from Iczelions site.


I have tried to modify it to work with MASM as follows:

[code]

.386
.model small
.code

push ebp
mov ebp,esp

mov eax,12345678

mov esp,ebp
pop ebp
ret 16
END
[/code]

The .386 forces MASM to build 32 bit code, the stack handling is not necessary as there are no stack parameters and you are using a dos segmented memory model for an EXE file, not a COM file.

Let us know what you are trying to do and I am sure some of our members can help you if it can be done.

Regards,

hutch@movsd.com
Posted on 2002-02-21 20:09:45 by hutch--
The end result is to learn a little about assembler and create a simple CPU signature procedure that can be called from Visual Basic.

At this point, I'm simply trying to create a Com file with MASM.
I got the Microsoft Linker (version 5.63) from Iczelion's site.

But I don't know how to create an COM file with it. The original MASM linker has a 'Link.txt' file with the switches for it, but the MS 5.63 linker didn't have one. Do you know the switches for link.exe to make it work? I've attached a zip file with my asm, obj and bat files.

When I try a simple link, It wants the exe name, etc and doesn't like the first byte, which is 4C. 'Fatal Error L1101: invalid object module, Object file offset: 1 Record type: 4c'.

Next I try to create a simple routine that has values passed to it from Visual Basic based on the example below. Finally, I'll try to get the CPU signature based on the example Pascal code I've attached below. Whew, this is a lot for me. But I'm gonna try.

Thanks for your help - Jack Rasnick




Example asm to get parameters from CallWindowProc api call
----------------------------------------------------------
;This gets param into eax and to res&
USE32

long1 equ
long2 equ
long3 equ
long4 equ

push ebp
mov ebp,esp

mov eax,long1

mov esp,ebp
pop ebp
ret 16





Example Pascal code that I'll try to convert
-----------------------------------------------------
function AzCpuSignature: Longword;
{ -> none
<- dword processor signiture or 0
0..3: Stepping
3..7: Model
7..11: Family
11..13: Type
13..32: Intel reserved
}
asm
CALL AzHasCpuId
CMP AL, TRUE
JNE @Unknown

PUSH EBX
XOR EAX, EAX
DW $A20F
POP EBX

CMP EAX, 1
JL @Unknown
JMP @CpuId1

@Unknown:
XOR EAX, EAX
JMP @End

@CpuId1:
PUSH EBX
MOV EAX, 1
DW $A20F
POP EBX
@End:
end;

function AzHasCpuId: Boolean;
{ -> none
<- True if processor can execute CPUID instruction. False otherwise.
Function tries to modify ID bit in Flags }
asm
MOV EDX, FALSE
PUSHFD
POP EAX
MOV ECX, EAX
XOR EAX, $200000
PUSH EAX
POPFD

PUSHFD
POP EAX
XOR ECX, EAX
JZ @Skip
MOV EDX, TRUE
@Skip:
PUSH EAX
POPFD
MOV EAX, EDX
end;
Posted on 2002-02-22 13:50:41 by JackRazz
Jack,

It really depends what you are trying to do with the asm file you want to build. If you make a DOS com file and call it from VB, it will run in the DOS 16 bit subsystem, not in 32 bit so you cannot call it that way and get a return value back at all.

What I would suggest is building a DLL in MASM as you can both call it from VB and get a return value back from it with no problems at all. It is in fact a good way to target speed critical operations for a VB program.

Now if you want the info for using the old linker, just run it from a dos box and redirect the output to a text file.


LINK /? > linkhelp.txt


This is the only piece of DOS com code I have left, lost the rest on a dead disk a fw years ago.



;----------------------- Hello.ASM ----------------------------

com_seg segment byte public ; define the ONLY segment

assume cs:com_seg, ds:com_seg ; both code & data in same segment.
org 100h ; go to start adress in memory.

start:
mov ah, 40h ; the DOS function number.
mov bx, 1 ; the screen handle.
mov cx, 11 ; the length of the text to display.
mov dx, offset Greeting ; the address of the text.
int 21h ; get DOS to execute the function.

mov ax, 4Ch ; the TERMINATE process function.
int 21h ; call DOS again to EXIT.

Greeting db "Hello World",13,10 ; specify the text as byte data.

com_seg ends ; define the end of the segment.

end start

;----------------------------------------------------------------


the code example you are posting LOOKJ like 32 bit code so building a DLL may be the best way for you to go. There is an example in the MASM32 package on how to do a basic DLL.

Regards,

hutch@movsd.com
Posted on 2002-02-22 20:45:28 by hutch--
Jack,

I've one question for you before you kill yourself doing it this way. Mine you, I like VB, and remember the 'good old days' when any programmer would code his interface in Basic, and drop in assembly statements for speed. (For you youngsters out there, this is in the pre-PC days).

I would ask why use the CallWindowProc to call the code? Wouldn't a simple dll call be easier to impliment? Or for someone else to follow? Not to mention probably faster too since it lacks the message proccessing API overhead.

Or even a Component Object Model COM style interface for even simpler reuse?

In any case, if you do go your way and get this to work, I would appreciate seeing an example.
Posted on 2002-02-23 22:59:46 by Ernie
Ernie,
Thanks for the reply. Its primarily license code that I don't want exposed with a public dll interface. If the cpu signature (used to identify hardware) were exposed in a dll, it would then need to be encrypted (which I've already done in vb) to prevent a hacker from simply replacing the dll. Based on the example code attached, it should have been fairly easy to embed it. I have a CRC32 class module where someone else did it.

Speed isn't important. In a lot of ways, it looks like a stupied hack (more maintenance, less readable, etc), but I simply didn't want to take a lot of trouble fixing an exposed dll. I even have a Delphi class module ready to wrap into a dll, so yes, its more work.

It would have been very small so it would have fit in a 1 line string easy. I've run into a brick wall because I cannot link 32 bit code into machine code (COM file) and I don't know enough about assembly to do it. I'm stuck

Jack Rasnick:confused:
Posted on 2002-02-24 00:18:11 by JackRazz
This is the original example code showing how to embed machine code into the vb project itself.
Posted on 2002-02-24 00:23:58 by JackRazz
Jack,

One of the few guys I know who is fluent in these sort of tricks with VB is a guy who hangs in the #win32asm channel on EFnet by the nick of cynica_l or variations of the same.

I vaguely recollect him speaking of a method of adding an OBJ file into VB during its build stage.
An old version of CL.EXE and a version of LINK.EXE were available for compiled VB programs and it has something to do with stopping the process during build and adding the extra obj module.

Maybe its worth giving that a try.

Regards,

hutch@movsd.com
Posted on 2002-02-24 23:21:36 by hutch--
hutch,
Thanks for the info. I'm currently loading the machine code from the obj file, by starting at byte &H65 in it. There may be serious drawbacks to doing this, but it seems to be working. I'm slowly learning assembler by doing everything wrong and spending a lot of time figuring it out. This is typical for me. First return a simple number (mov eax,12345), then return a argument (mov eax, long1) and so on.

At the moment, no debugger due to the approach I'm using - I may revise the way i'm doing it to get it. Lets see, add the includes, figure out where the main procedure starts and finally start the CallWindowProc from there:cool:.

Sometimes you have the most fun by just playing and not reading books, instructions, etc. I may look for a simple assembler book tomorrow.

Thanks again - Jack

ps. - I like your wizard. Just saw the Lord of the Rings director discussing his wizard char on charlie rose last night.
Posted on 2002-02-25 22:47:10 by JackRazz