Hello all,
I am experimenting with OpenWatcom, trying to compile a simple C
file into a COM executable. The tricky part is that I'd like to avoid
pulling in watcom's standard library and startup code in the process.
I have such TEST.C file:
void main(void) {
static char *hello = "Hello$";
_asm {
mov ah, 9
mov dx, hello
int 0x21
}
}
I filled TEST.LNK with the following directives:
FORMAT DOS COM
FILE test.obj
OPTION NODEFAULTLIBS
NAME TEST.COM
OPTION START=main_
I do get "something" out of this, but the binary file does not work
properly. The disassembled COM looks like that:
00000000 53 push bx
00000001 51 push cx
00000002 52 push dx
00000003 56 push si
00000004 57 push di
00000005 B409 mov ah,0x9
00000007 8B160C00 mov dx,[0xc] <-- this should be 0x11C
0000000B CD21 int 0x21
0000000D 5F pop di
0000000E 5E pop si
0000000F 5A pop dx
00000010 59 pop cx
00000011 5B pop bx
00000012 C3 ret
00000013 004865 add [bx+si+0x65],cl
00000016 6C insb
00000017 6C insb
00000018 6F outsw
00000019 2400 and al,0x0
0000001B 0004 add [si],al <-- this should be 0x114
0000001D 00 db 0x00
It appears that the COM file is not being originated at offset 0x100,
despite the "FORMAT DOS COM" wlink directive. It's also not
0-originated, so I am not sure how the offsets are calculated exactly.
Once I fix them with a hex editor, the executable works.
Sure, but the variable at hand is a pointer, so what I am effectively interested in is where it points to (ie. its content). The variablevoid main(void) {
static char *hello = "Hello$";
_asm {
mov ah, 9
mov dx, hello
int 0x21
}
}
The `hello` from `mov dx, hello` in assembly's perspective, means the
content of the variable. Not its address.
Yes, and the program I posted does work all right when linked asFORMAT DOS COM
FILE test.obj
OPTION NODEFAULTLIBS
NAME TEST.COM
OPTION START=main_
I'm not familiar with Watcom linker, but the linker user's guide says
to use these:
system com
If you disassembed a binary using a blind disassembler (which don'tThis is a COM file, so it's raw code. The only data here is the "hello"
know binary file format, and platform), all file bytes will be
treated as code, and will start at zero or at disassembler
application's predefined address.
Also check the compiled binary. Make sure it doesn't start with "MZ",I posted the exact, full content of the binary. It's a COM file, no MZ.
looking for a way of building minimalist COM files using the C
language, hoping that Open Watcom would be able
Hello all,If you make your own startup code with proper
I am experimenting with OpenWatcom, trying to compile a simple C
file into a COM executable. The tricky part is that I'd like to avoid pulling in watcom's standard library and startup code in the process.
I have such TEST.C file:
void main(void) {
static char *hello = "Hello$";
_asm {
mov ah, 9
mov dx, hello
int 0x21
}
}
I compile it into an object and pass to wlink using these commands:
wcc -0 -ms -od -s -d0 -zl -zls test.c
wlink @TEST.LNK
I filled TEST.LNK with the following directives:
FORMAT DOS COM
FILE test.obj
OPTION NODEFAULTLIBS
NAME TEST.COM
OPTION START=main_
I do get "something" out of this, but the binary file does not work properly. The disassembled COM looks like that:
00000000 53 push bx
00000001 51 push cx
00000002 52 push dx
00000003 56 push si
00000004 57 push di
00000005 B409 mov ah,0x9
00000007 8B160C00 mov dx,[0xc] <-- this should be 0x11C
0000000B CD21 int 0x21
0000000D 5F pop di
0000000E 5E pop si
0000000F 5A pop dx
00000010 59 pop cx
00000011 5B pop bx
00000012 C3 ret
00000013 004865 add [bx+si+0x65],cl
00000016 6C insb
00000017 6C insb
00000018 6F outsw
00000019 2400 and al,0x0
0000001B 0004 add [si],al <-- this should be 0x114
0000001D 00 db 0x00
It appears that the COM file is not being originated at offset 0x100, despite the "FORMAT DOS COM" wlink directive. It's also not
0-originated, so I am not sure how the offsets are calculated exactly.
Once I fix them with a hex editor, the executable works.
What am I missing here?
If you make your own startup code with properIs org 100h really required in this context? Isn't it the job of the
----8<----
org 100h
_cstart_:
...
end _cstart_
----8<----
It may just work.
I filled TEST.LNK with the following directives:...
OPTION START=main_
00000007 8B160C00 mov dx,[0xc] <-- this should be 0x11C
0000001B 0004 add [si],al <-- this should be 0x114
Without "OPTION START" the result is exactly the same, with the onlyOPTION START=main_
A COM file *always* starts at 0x0100. Maybe this directive
interferes with it ?
The only wlink options I found in this context are "FORMAT DOS COM" and00000007 8B160C00 mov dx,[0xc] <-- this should be
0x11C
the 0xC is almost the offset from that commands address to the string
(off by one). IOW, it looks like the resolving (by "wlink") didn't
quite kick in. Maybe the linker needs to be told that it is
converting a COM style program too ?
You are correct that 0x1B is beyond code, but it is not beyond data.0000001B 0004 add [si],al <-- this should be 0x114
AFAIKS everything from address 0x1A is beyond your code/program.
IOW, no idea what the remark is about.
A COM file *always* starts at 0x0100. Maybe this directive
interferes with it ?
Without "OPTION START" the result is exactly the same, with the only >difference that wlink complains about "no starting address found".
0000001B 0004 add [si],al <-- this should be 0x114
AFAIKS everything from address 0x1A is beyond your code/program.
IOW, no idea what the remark is about.
You are correct that 0x1B is beyond code, but it is not beyond data.
My understanding is that the "04 00" value starting at 1Ch is a near
pointer that is supposed to be loaded by mov dx,[0x0c]
How the values 0x000C and 0x0004 have been computed exactly, this
I have no idea.
dn. Wed, 2 Aug 2023 20:28:34 -0700 (PDT), Alexei A. Frounze napisa+e:Perhaps, but that's how the OBJ/OMF format has worked for years
If you make your own startup code with properIs org 100h really required in this context? Isn't it the job of the
----8<----
org 100h
_cstart_:
...
end _cstart_
----8<----
It may just work.
linker to compute proper addresses?
I tried nonetheless, but nasm does not understand the "org" directiveWhy not just use WASM if you're already using WCC/WCL/WLINK/etc?
when using the -f obj target. It's apparently only valid for -f bin.
00000000 53 push bx...
I didn't know that, I naively assumed the linker would recompute allIs org 100h really required in this context? Isn't it the job of
the linker to compute proper addresses?
Perhaps, but that's how the OBJ/OMF format has worked for years
in TASM, MASM, WASM.
The first object file containing code should start its codeThanks for your research, it does explain quite some things. For
segment with a line like `RESB 100h'. This is to ensure that
the code begins at offset `100h' relative to the beginning
of the code segment, so that the linker or converter program
does not have to adjust address references within the file
Could you add a command like "lea ax,main" and see which addressHere it is:
"main" gets translated too ? It should ofcourse show 0x0100. If it
does not not than the linker didn't generate a COM style file to
begin with.
Also, have you checked the binary contents of your (supposed) .COMThe disassembly I posted in the initial message truly is the entirety
file ? If it starts with "MZ" ...
It appears that without startup code, wlink simply won't generate
a proper COM.
I noticed that you are compiling with the "-ms" switch"-ms" is the proper switch for compiling object files for COM
(small memory model), which is incompatible with a COM style
executable. Try "-mt" (tiny memory model) instead.
Try "-mt" (tiny memory model) instead.
"-ms" is the proper switch for compiling object files for COM
executables. In fact, the wcc compiler doesn't even understand -mt.
Building a COM itself is well documented and hence easy to achieve.
The problem here is that I was trying to make Open Watcom build a tiny
(as in "very small") COM file by avoiding Watcom's libc and startup code,
Then the COM file indeed becomes very small, but it also ceases working,
as the generated code seems to expect to be executed within an environment prepared by Watcom's startup routines.
Thats too bad. At least you can't say I didn't try. :-)And your kind effort is very much appreciated. :)
Strange. Being able to specify a DOS COM output, but not actuallyIndeed. It's COM all right, but only as long as one links to the Watcom-supplied startup library (or equivalent). If not, then all bets
getting it. :-\
It appears that the COM file is not being originated at offset 0x100,Hello all,
despite the "FORMAT DOS COM" wlink directive. It's also not
0-originated, so I am not sure how the offsets are calculated exactly.
Once I fix them with a hex editor, the executable works.
What am I missing here?
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 65 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 62:45:26 |
| Calls: | 862 |
| Files: | 1,311 |
| D/L today: |
10 files (20,373K bytes) |
| Messages: | 264,046 |