2023-02-02
Yesterday rr asked about the syntax for the Debug command S (search memory).
I replied that lDebug can search an entire segment using eg s E000:0 l 10000 "DIP"
or s E000:0 FFFF "DIP"
. I also stated that the latter should work in Microsoft's Debug too.
However, he replied that a range from an offset 0 to offset FFFF doesn't work in Microsoft's Debug. Other end values such as 7FFF, FFF0, and even FFFE do work however.
I first suspected that the search mask length may be involved. This is not correct however.
Upon learning that start offset 0 and end offset FFFE worked with a 3-byte search mask, I quickly deduced that Debug doesn't contain special support for range lengths of a full 64 KiB. Because some of the debugger's internal handling uses a 16-bit value as the length, and does not encode it as in "this is the length minus 1" or "a value of zero means 64 KiB", the lengths it can theoretically handle are all unsigned 16-bit numbers, up to FFFFh, including a zero length.
I tested my suspicion by issuing a range of 1 FFFF
and… it worked! Looking at the sources of my msdebug recreation (based on the free software MS-DOS v2 release), it became apparent that it specifically detects incrementing a length to 0 and errors out, avoiding needing to special case a 64 KiB length elsewhere.
During the review I also noticed that there is no check for the search range length being at least as large as the search mask length. This makes it not work correctly nor error out on a command like s 0 1 "123"
. Instead of erroring or returning no result, it acts as if a large length was given.
I found that lDebug does error out for this case, but it will cause an error in the sequence of hack calls (in the next hack-using command like S or D) because the search error is handled after prephack
and dohack
have already been called. Further, si does not point into the debugger's input line at that point anymore so the error carat display will generally be wrong.
2023-02-03
This draft is meant to address rr's haste in reading the manual's section on the S command, which did not explain the parameter types referred to as range and list.
Quick start for reading this manual
The interface reference explains the basics of the debugger's interface and lists some common commands.
The parameter reference lists the types of parameters used by the available commands.
The command reference describes most commands in detail.
The expression reference details how numeric parameters are parsed by the expression evaluator.
The variable reference lists a subset of the debugger's variables and what they can be used for.
The interrupt reference lists what interrupt hooks the debugger sets up.
The service reference lists what services are called by the debugger, which may be useful for developers of the debugger, or of kernels, ROM-BIOSes, or DPMI hosts.
The online help pages provide some additional descriptions not found elsewhere in the manual, as well as overviews of many different topics.
The command help lists most of the switches and parameters accepted by the debugger and the instsect program.
The news lists an overview of changes since prior releases of lDebug.
Invoking the debugger states how to start the debugger, either bootloaded, as a device driver, as an application, or through the test suite.
Building the debugger lists components, build options, and instructions on how to build.
Debugging the debugger itself lists some considerations for working with CDebug or DDebug as a debuggee.
The additional usage conditions section lists attribution and licenses for the various depackers that can be used for the compressed debugger executable.
Source Control Revision ID gives the Mercurial hash of the manual's source revision, and links to that revision in ecm's repository.
For a tour, definitely start with the interface reference. To help invoke the debugger read the section on Invoking the debugger as an application. It may help to read the manual while testing the debugger on another terminal. Use the main page of the online help as a reference to what is possible, then check the command reference for details. To explain what parameter types are used refer to the parameter reference. For how to calculate refer to the expression reference.
Reconfiguring the debugger can be done using variables, including the Debugger Assembler Options (DAO) and the Debugger Common Options (DCO) 1 to 6. Use the variable reference and the online help pages on the options for those. Change variables using the R commands, such as r dco or= 800
or r ior := #50
.
Some tips:
GT
or GNT
commands to skip past conditionalsG ABO
to skip past calls or loops if P
would not workPOINTER
type expression allows using a 32-bit number as a 16:16 segmented address whereever an address parameter is parsed(…)
AGAIN
keyword as the first breakpoint, and can save to the list without actually executing the debuggee by ending the breakpoint list with a REMEMBER
keywordINSTALL AMIS
and INSTALL TIMER
commands can be used to provide the debugger's AMIS interface and hook the timer interruptDW ss:sp
command is useful to view the current stack formatted as words[more]
prompt that pauses the output until a keypress is receivedBP NEW ptr ri2Dp
, if the interrupt handler is writeable#
prefix, and binary with 2#
. Character codes can be used as numbers with #"…"
tp FFFFF while ! value from linear 0:1*4 length 3*4 in writing silent
. Add a conditional breakpoint like bp new ptr ri21p when value ax in 2501, 2503
beforehand to intercept DOS calls to change these interruptsg word [ss:sp]
. For a 16-bit far or interrupt function use g ptr [ss:sp]
G AGAIN address REMEMBER
(insert an offset or (NOT)TAKEN
keywords for the address), then finally run G AGAIN
?O
help page as well as individual pages like ?O6
for DCO6?BUILD
displays the description and source control revision IDs. The description includes a build date or release number.