Creating Line Fragments Using DEBUG


DEBUG can create a "line fragment" (a line without the usual carriage-return). No assembly language required! Just use DEBUG as a binary editor. 

Like lots of DOS commands, DEBUG can be run from the keyboard or from a redirected file. In the batch file below, I use ECHO to create a file (unimaginatively named SCRIPT) which will be redirected into DEBUG:

echo e 100 "set value="> script
echo rcx>> script
echo a>> script
echo n fragment.txt>> script
echo w>> script
echo q>>script
debug < script > nul
del script

The above batch code will create a "script" file containing this:


e 100 "set value="
rcx
a
n fragment.txt
w
q

Let's examine the script file which will be created. You could actually start debug and hand-enter all the above commands. First we Enter (starting at address 100, the default beginning of all debug files) some text. This could be either space or comma delimited hex values or quoted text. I chose to enter SET VALUE=. You could enter whatever you wanted. Obviously, in this example I'm planning on creating an environment variable named VALUE and filling it with something! Next I need to set the file size. This part requires you to count characters. My text uses a total of 10 characters (which is hex A). The file length is stored in the CX register, and the RCX command allows us to enter a new value for the CX register. The value we enter is A. At this point, everything in memory is the way we want it. We enter a Name for the file ( I chose FRAGMENT.TXT), then Write it to the disk. We can then Quit.

After running the above batch file, we would have a 10 byte file named FRAGMENT.TXT containing only SET VALUE= with no CR/LF at the end of the line. 


Obviously, if you know exactly how long your text is going to be (10 bytes in this example), you could simply set the CX register appropriately (to A in this case). If you want to create a more general utility that could accept any reasonable line, you might try this trick: Fill a line with EOF characters (hex 1A). Let your desired data overwrite some of the EOF characters. When DOS processes this frankenstein line, it will ignore all the EOF characters. Believe it. Here's what you do:

echo f 100 L 80 1a> script
echo e 100 %2 %3 %4 %5 %6 %7 %8 %9>> script
echo rcx>> script
echo 80>> script
echo n %1>> script
echo w>> script
echo q>>script
debug < script > nul
del script

This will Fill memory starting at address 100 (the default) for a Length of 80 (hex) with the DOS end-of-file character 1A. 80 hex is 128 decimal, which is the maximum command-line length. You would pass the file name as the first argument and your desired text as additional arguments. You'd be replacing the inflexible FRAGMENT.TXT and SET VALUE= with the more general %1 and %2. If it became important to clean the resulting file up (set it's length so there were no EOF characters in it), it could be accomplished by either of the two methods:
copy /a fragment.txt clean.txt
type fragment.txt > clean.txt
Of course, if we use COPY to concatenate text files, we won't need to specify the /a switch:
copy fragment.txt + someline.txt result.txt
Typically, SOMELINE.TXT would contain a file name or other important data, and RESULT.TXT would be a batch file (Maybe I should've called it RESULT.BAT ?)


If you're determined to create a COM file ahead of time, you might want to investigate ECH.COM, a replacement for the ECHO command which doesn't add the terminating CR/LF to the end of the line. 

Here's a trick that combines the fragment, a batch file, and a debug script all in one. As presented, it creates a fragment, adds whatever you want to the fragment to create a new line, then executes the new line (assuming the new line is a batch file).

@echo off
echo set value=> ~.bat
echo e 010a 1a >> ~.bat
echo w >> ~.bat
echo q >> ~.bat
type ~.bat | debug ~.bat> nul
type ~.bat | more> ~.bat
echo Your Command Output Goes Here!>> ~.bat
call ~.bat
del ~.bat

First we put SET VALUE= (with an unavoidable carriage return at it's end) in the file. Then we append a DEBUG script to the same file. Don't worry, DEBUG ignores batch commands and won't have a problem modifying it's own script. The E 010A 1A will Enter the value 1A (the end-of-file character) at the address 010A. Since the file always starts at 0100, this is "A" (ten) characters in. The "s" in "set value" is the zero character, the "e" is the first, the "t" is the second, ... which makes the tenth character just after the equal sign. The ECHO W will cause the DEBUG script to Write our change to the disk, and the ECHO Q will Quit DEBUG. We then TYPE the script into DEBUG and redirect it's output into NUL so as not to garbage up the screen. Using TYPE and the "pipe" is what allows DEBUG to seem to modify a running script! The next step is to chop our file off where we inserted the end-of-file character. The TYPE ~.BAT | MORE > ~.BAT does this. The chopping is done by the TYPE command, but I pipe it through MORE just to gain an intermediate step which allows me to use the same name for the output file. MORE has the interesting habit of adding a carriage return to the start of a file, but I am only concerned with protecting the end of my file, so this is okay. Now you can append anything you want any way you want. The end result of ~.BAT in this example is
set value=Your Command Output Goes Here!



Alec Bennett noticed that the above DEBUG solution for creating file fragments doesn't work under XP. Alec noticed that the cmd.exe and command.com relationship means that the first file that you send through debug to create a fragment can't be deleted. Normally, of course, you'd use the XP/NT/2000 "for" command to do anything you'd think might need debug. However, if you want to write code that will run on all platforms and you want to avoid unreliable platform testing and having to maintain separate code bases, you might want to try out Alec's "Universal fragment creation with DEBUG" (shown below) that works on 95/98/NT/XP/2000. Alec uses the hybrid quote/variable method to create the temporary "Create1.bat", and the spaces method to create "Create2.bat" file. The Create1.bat is then started in a separate process, then it launches Create2.bat in a separate shell to do the real work of creating the fragment. A separate process launching a separate shell? Now that's what I call isolation! The CLS and ECHO OFF commands are used to insure the windows close properly under Win9x.

@ECHO OFF
:Fragment
ECHO Creating file fragment . . .
TYPE Main.bat | FIND "%%""Create1%%" > Create1.bat
TYPE Main.bat | FIND " " | FIND /V "BUT NOT THIS LINE!" > Create2.bat
START /WAIT /MIN Create1.bat
ERASE Create1.bat
ERASE Create2.bat
ECHO Done.
GOTO END
%"Create1% ECHO OFF
%"Create1% COMMAND < Create2.bat
%"Create1% CLS
%"Create1% EXIT
ECHO E 100 "SET FILENAME="> Script
ECHO RCX>> Script
ECHO D>> Script
ECHO N Fragment.txt>> Script
ECHO W>> Script
ECHO Q>>Script
DEBUG < Script > NUL
ERASE Script
EXIT
:END
CLS
EXIT


 

Lost? Look at the site map.

Bad links? Questions? Send me mail.

Google
Yahoo
Ask Jeeves