.. debugging
Debugging refers to the removal of errors in your program. Admiral Grace Hopper (an early computing pioneer)
liked to tell a story in which a technician solved a glitch in the Harvard Mark II machine by pulling an
actual insect out from between the contacts of one of its relays.
The debugger allows you to single step through code, stop execution at critical points
and examine registers and memory - WHILE your program is running!
- Step through code (step into, step over)
- Examine registers (right click for flags)
- Examine memory (&Var1 or address)
- Watch (Right click on Var1, add watch)
- View disassembly (right click options) of HOL
.. emu8086 debugger
Running and Debugging
Emulator:
- View: memory
stack
variables
flags
- Debug: single step
set breakpoint
Extended Debug For The Emulator
- - Use these commands in the debug log
- - - - View log and debug.exe emulation
- c - compare several bytes (arrays). For example:
org 100h
jmp a
v1 db 1,4,3,4,5,6,7
v2 db 1,5,3,0,5,6,7
a:
mov ax, v1
mov al, v2
mov dx, v1
mov dl, v2
ret
To compare v1 and v2 type the following:
c v1 L 7 v2
L denotes the size of the array. If L parameter is not specified this command compares 8 bytes by default. For example to compare 8 bytes at offsets CS:100 and CS:233 type the following:
c 100 233
It is also possible to use registers as parameters, for example:
c SI L 20h DI
The command outputs only those addresses with values that are different.
Equal bytes are not printed out.
- i - input and display byte from a specified port. For example:
i 123
To input a word value use iw command.
- o - output byte to a specified port. For example:
o 123 55
To output a word value use ow command. For example:
ow 123 5512
- d - dump 128 bytes at specified address. For example:
d ds:3
d ds:[bx]
d ds:[bx+si]
d bx + 5
d 10
If no segment is specified CS is used by default. Square brackets are optional.
Subsequent use of d command without parameters shows next block of the memory.
L parameter can be used to specify the number of bytes to dump. For example:
There must be spaces around L to distingush from variable offset, for example:
d lion L 10
The above command dumps 16 bytes at offset of a variable called lion.
If requred to denote variable L, declared as L db 5, brackets must be used. For example:
d [L]
d [L] L 1
- t - single step.
- p - step over (procedure or interrupt).
- r - show all registers and current instruction at CS:IP.
- rf - view/set flags.
- r [register name] - view/set register value.
Code Examples to Look at in Debug
.. Code with bugs...
; Wyatt, 11/11/2011
;
; Demonstrate 'bugs'
;
; Supposed to loop thru the array, adding
; each element.
; setup a pointer
; setup loop counter
; loop
; add each element in the array
; bump pointer to next element
; end loop
; multiply answer by 2
;
; goto part2 where it does ?
; FILE WITH MACROS & PROCS
include emu8086.inc
; ADDRESS WHERE CODE WILL BE LOCATED
org 100h
; CODE
lea si, array
mov cx, 3
mov ax, 0
L1:
add ax, [si]
add si, 1
loop L1
shl ax,1
call PRINT_NUM
jmp part2
ret
; DATA
array dw 1,2,3
sum dw 0
; PROCEDURES (call)
DEFINE_PRINT_NUM ; prints AX signed
DEFINE_PRINT_NUM_UNS ; prints AX unsigned - required for print_num.
PART2:
; CODE
mov cx, 256
mov ah, 2
mov dl, 65
L2:
int 21h
inc dl
loop L2
ret
; stop assembling here
END
.. Hello one character at a time: pointer and interrupt emu8086
; "hello, world!" step-by-step char-by-char way...
; this is very similar to what int 21h/9h does
name "hello"
org 100h ; compiler directive to make tiny com file.
; execution starts here, jump over the data string:
jmp start
; data string:
msg db 'Hello, world!', 0
start:
; set the index register:
mov si, 0
next_char:
; get current character:
mov al, msg[si]
; is it zero? if so stop printing:
cmp al, 0
je stop
; print character in teletype mode:
mov ah, 0eh
int 10h
; update index register by 1:
inc si
; go back to print another char:
jmp next_char
stop:
mov ah, 0 ; wait for any key press.
int 16h
; exit here and return control to operating system...
ret
end
.. Sum an Array: Multi-segment (exe) emu8086
- show memory before
- show memory after
- explain
; multi-segment executable file template.
include emu8086.inc
data segment
x DW 100b, 100d, 100h, 100o ; CAREFUL!
len = $-x
y DW 0
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
; set up pointer to x
; -----------------
lea di, x ;mov di, OFFSET x
; set up loop counter
; -----------------
mov cx, len
shr cx, 1
; init ax to 0
;-----------------
mov ax, 0 ; xor ax, ax
; sum array items one at a time...
L1:
add ax, [di] ; add what di points to to AX
add di, 2 ; bump pointer
loop L1 ; repeat until CX = 0
call print_num
ret
define_print_num
define_print_num_uns
end
Other Debuggers
.. visual studio debugger
.. debug an exe w/o source & debug utility