Ive seen masm be used to usefully arrange code/data in snazzy ways (you can manipulate the compiler counter, put data in code sections etc etc). What i need to do is make kindof short data file which is basically a large array of rects. I also need a region with data pointers to it (a kind of index). Is there any way of using masm to arrange my data.
For example (im just trying to get what i want to do accross, this is probably a load of rubbish) i could do something like
.data
initheader db "dat", 0
pdata1 DWORD ADDR data1
pdata2 DWORD ADDR data2
data1 db 34h, 34h, 70h, 98h
data2 db 80h, 90h, 80h, 90h
So basically i would "compile" end up with a file like this
mydata.dat (hex)
0000 db "d", "a", "t", 00, 00, 00, 00, 0C
0008 db 00, 00, 00, 10, 34, 34, 70, 98
0010 db 80, 90, 80, 80
Can i do this with MASM, or shall i create my own program to do it for me? :bg
Cheers :U
One possible method:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
mydata LABEL byte
initheader db "dat", 0
pdata1 dd OFFSET data1
pdata2 dd OFFSET data2
data1 db 34h, 34h, 70h, 98h
data2 db 80h, 90h, 80h, 90h
lendata EQU $-mydata
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke write_disk_file, chr$("mydata.bin"),ADDR mydata,lendata
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Good idea :D
Problem with that is that wouldnt all the OFFSET addresses be wrong?
Is it possible to replace it to something like?
pdata1 dd (OFFSET data1 - OFFSET pdata1)
Yes, the offsets would be wrong. I should have seen that when I looked at the output file.
pdata1 dd OFFSET data1 - OFFSET mydata
pdata2 dd OFFSET data2 - OFFSET mydata
00000000 :64 61 74 00 0C 00 00 00 - 10 00 00 00 34 34 70 98
00000010 :80 90 80 90
Why not create a binary instead of an executable (no obj file, just a bin). You can do that with ANY assembler. Most people think an exe file is a binariy file but it is not, a binary file contains no headers, just the assembly. In fact, I think this is the only type of file that sol_asm can create at the moment if memory serves. Take a look at your assmbler options.
Paul
Paul,
You honour me :)
Yes Sol_ASM is able to create plain binary files (actually the only thing it can create for now)....
What i have released until now is interesting for study (sources) but not usable yet; maybe the next release;)
Until then i guess you can create plain binary files by using a special linker like JLOC. This linker can create a plaing binary form an OBJ created by MASM, TASM, etc.
Also AFAIK FASM cand also directly output plain binary files.
However I guess that MASM's license does NOT allow any other usage besides Windows API/DirectX Applications or KMD drivers.
With the aid of a 16-bit linker you could readily use MASM to create a binary file, but the file size would be limited to 64KB. A method that I think should work for larger files is here (http://www.adras.com/How-to-make-a-binary-file-in-masm-no-linker-required.t625-151.html). But I think I would still go with the exe and write the data to a file at run time.
That's a pretty cool trick Michael! However it doesn't work in XP, at least for me. Debug is not producing an output. This is what is being done in debug:
-a 0
13A8:0000 mov cx, [124]
13A8:0004 mov bx, [126]
13A8:0008
-p=0 2
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13A8 ES=13A8 SS=13A8 CS=13A8 IP=0004 NV UP EI PL NZ NA PO NC
13A8:0004 8B1E2601 MOV BX,[0126] DS:0126=0000
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13A8 ES=13A8 SS=13A8 CS=13A8 IP=0008 NV UP EI PL NZ NA PO NC
13A8:0008 1DF04F SBB AX,4FF0
-w 18C
Writing 00000 bytes
It's missing something in the writing stage, but I haven't identified what yet.
Hmm, debug write == dependent on source file extension present. <shrug...>
Here's a version which seems to work on XP Pro. Stripped the BOCHS stuff and renamed output to .bin. Save as .bat or .cmd file in 2k/NT/XP and run it. :)
;@echo off
;REM Original by Mike Gonta (a.k.a. "look and see")
;if exist %~n0.bin del %~n0.bin
;ml.exe /nologo /c /coff %0
;ren %~n0.obj %~n0
;echo a 0 > dbg
;echo mov cx, [124] >> dbg
;echo mov bx, [126] >> dbg
;echo. >> dbg
;echo p=0 2 >> dbg
;echo w 18C >> dbg
;echo q >> dbg
;echo. >> dbg
;debug %~n0 < dbg
;del dbg
;ren %~n0 %~n0.BIN
;goto end
option casemap :none
option dotname
.686p
.model flat, stdcall
.code
start:
nop ; your masm code here
end start
;:end
;pause
The original batch file was intended to extract the code section from the object module. In this case we need to extract the data section. If I change the source to this (test.asm) :
.386
.model flat, stdcall
.data
mydata LABEL byte
initheader db "dat", 0
pdata1 dd OFFSET data1 - OFFSET mydata
pdata2 dd OFFSET data2 - OFFSET mydata
data1 db 34h, 34h, 70h, 98h
data2 db 80h, 90h, 80h, 90h
end
Then this will work:
if exist test.obj del test.obj
\masm32\bin\ml /c /coff test.asm
pause
echo a 0 > dbg
rem For .data section size of raw data is dword
rem at offset 4Ch, but DEBUG will load object
rem module starting at offset 100h.
echo mov cx,[14c] >> dbg
echo mov bx,[14e] >> dbg
echo. >> dbg
pause
echo p=0 2 >> dbg
rem For .data section, for this particular source
rem layout, the raw data will start at offset 64h.
echo w 164 >> dbg
echo q >> dbg
echo. >> dbg
pause
debug test.obj < dbg
del dbg
pause
copy test.obj test.bin
echo.
rem Enter d 100 at prompt to display data
debug test.bin
One problem with this method is that changes to the source layout (adding a code section for example) will cause the raw data to move in the object module. For maximum flexibility you would need to get the pointer to the raw data from the object module, which in my limited testing was always at offset 50h, but I can see no reasonable method of using this value as the starting source address for the DEBUG Write command.
Also, this method cannot produce data files much larger than about 500KB because DEBUG would not be able to load the object module.
Mark,
I will test that, also so we can look at it from two directions. I wonder what XP's problem is? I looked at Michael's code and it looks pretty straight forward, IYKWIM.
Paul
Quote from: Mark Jones on April 29, 2006, 09:55:08 PM
-a 0
13A8:0000 mov cx, [124]
13A8:0004 mov bx, [126]
13A8:0008
-p=0 2
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13A8 ES=13A8 SS=13A8 CS=13A8 IP=0004 NV UP EI PL NZ NA PO NC
13A8:0004 8B1E2601 MOV BX,[0126] DS:0126=0000
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13A8 ES=13A8 SS=13A8 CS=13A8 IP=0008 NV UP EI PL NZ NA PO NC
13A8:0008 1DF04F SBB AX,4FF0
-w 18C
Writing 00000 bytes
It's missing something in the writing stage, but I haven't identified what yet.
BX and CX are 0, so the write length is 0.
When you load any file other than an EXE file, the file is loaded without change, and BX and CX are set to show the number of bytes loaded.
Quote from: tenkey on May 05, 2006, 06:27:14 AM
When you load any file other than an EXE file, the file is loaded without change, and BX and CX are set to show the number of bytes loaded.
[Debug] wouldn't report a length if the loaded file contained an extension such as (*.obj) but as soon as the loaded file contained no extension, (*.) it then reported the length properly. That is why I say <shrug...> :bg
Debug sets BX:CX regardless of what type of file you load. The difference is that for an EXE Debug sets BX:CX to the size of the file less the size of the EXE header, instead of to the size of the file as it does for all other files.
Ok, but look at this code:
;ren %~n0.obj %~n0
;echo a 0 > dbg
;echo mov cx, [124] >> dbg
;echo mov bx, [126] >> dbg
;echo. >> dbg
;echo p=0 2 >> dbg
;echo w 18C >> dbg
;echo q >> dbg
;echo. >> dbg
;debug %~n0 < dbg
;del dbg
;ren %~n0 %~n0.BIN
Without the first line to rename the *.obj file to *. (no extension) DEBUG wouldn't return anything in BX and CX. So apparently the extension either needs to be .EXE or blank?
I'm not sure why the original code renamed the object module to remove the extension, because doing so will have no effect on Debug. Debug will load the file starting at offset 100h in its buffer and set BX:CX to the size of the file. For your code, if BX and CX are set to zero when the Write command executes then it's because the DWORD at offset 24h in the object module is set to zero. This would be correct for the object module for the last ASM code I posted, because the DWORD at offset 24h would be the size of the raw data for the nonexistent .text section.
@echo off
echo r > dbg
echo q >> dbg
echo. >> dbg
debug test.obj < dbg
if exist test del test
ren test.obj test
debug test < dbg
pause
del dbg
-r
AX=0000 BX=0000 CX=0014 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0B07 ES=0B07 SS=0B07 CS=0B07 IP=0100 NV UP EI PL NZ NA PO NC
0B07:0100 64 DB 64
-q
-r
AX=0000 BX=0000 CX=0014 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0B07 ES=0B07 SS=0B07 CS=0B07 IP=0100 NV UP EI PL NZ NA PO NC
0B07:0100 64 DB 64
-q
I realize now that in my last post I neglected files with a HEX extension. For these files Debug assumes an Intel HEX file, loads the number of bytes specified in the file, starting at the address specified in the file, and sets BX and CX to zero.