; ; GRDB ; ; Copyright(c) LADsoft ; ; David Lindauer, gclind01@starbase.spd.louisville.edu ; ; ; dis.asm ; ; Function: patch the dissassembly code together, display the output ; handle disassembler commands ; ;MASM MODE .model small .386 include prints.ase include operands.asi include operands.ase include opcodes.asi include opcodes.ase include mtrap.ase include input.ase PUBLIC diss,DisOneLine DEFAULTBYTES = 32 .data start dw 0 dend dw ? extraBytes dw 0 theSeg dw 0 .code isNewLine = bp - 2 ; Local variables oldposition = bp - 4 put = bp -6 bytestomove = bp - 8 ; ; Get a dissassembled line of code ; GetCodeLine PROC ENTER 8,0 mov WORD PTR [isNewLine],TRUE ; Assume it has an opcode mov BYTE PTR [di],0 ; Clear output buffer mov [oldposition],si ; Current position test [extrabytes],-1 ; See if still printing bytes jz short notextra ; from last instruction add si,[extrabytes] ; New position to edi xchg si,di ; mov BYTE PTR [si],0 ; Clear buffer mov al,10 ; Tab to pos 14 call TabTo ; xchg si,di ; edi = buffer push di ; mov cx,4 ; next four DWORDS = 0; sub ax,ax ; rep stosd ; Store the words pop di ; mov WORD PTR [isNewLine],False; Doesn't have an opcode jmp btm notextra: mov ax,[code_address] ; Get code address cmp ax,[dend] ; See if done jnc endcodeline ; Quit if nothing left xchg si,di ; esi = buffer push esi ; mov ax,fs ; call putword ; Put segment mov BYTE PTR [si], ':' ; Print ':' inc si ; mov ax,[code_Address] ; Get code address call putword ; Print it out mov BYTE PTR [si],' ' ; Put a space inc si ; mov BYTE PTR [si],0 ; Put an end-of-buffer pop eax xchg esi,eax push eax mov al,25 ; Tab to pos 29 call TabTo ; xchg si,di ; edi = buffer call ReadOverrides ; Read any overrides call FindOpcode ; Find the opcode table xchg si,di ; esi = buffer jnc short gotopcode ; Got opcode, go format the text push si ; Else just put a DB mov ax,"db" ; call put2 ; pop si ; mov al,TAB_ARGPOS ; Tab to the arguments call TabTo ; mov al,fs:[di] ; Put the byte out inc di ; Point to next byte call putbyte ; mov BYTE PTR [si],0 ; End the buffer xchg si,di ; pop edi ; jmp short btm ; Go do the byte dump gotopcode: push si ; Got opcode, parse operands mov si,di ; sub ax,ax ; assume 16-bit disassembly call DispatchOperands ; mov di,si ; pop si ; push di ; call FormatDisassembly ; Use the operand parse to format output pop di ; xchg si,di ; pop edi ; btm: mov BYTE PTR [di],0 ; End the buffer mov ax,si ; Calculate number of bytes to dump sub ax,[oldposition] ; mov [bytestomove],ax ; mov [extrabytes],0 ; Bytes for next round = 0 cmp WORD PTR [bytestomove],5; See if > 5 jbe short notmultiline ; No, not multiline mov ax,[bytestomove] ; Else calculate bytes left sub al,5 ; mov [extrabytes],ax ; mov WORD PTR [bytestomove],5; Dumping 5 bytes notmultiline: xchg si,di ; esi = buffer push di ; Save code pointer mov di,[oldposition] ; Get original code position mov cx,[bytestomove] ; Get bytes to move putlp: mov al,fs:[di] ; Get a byte call putbyte ; Expand to ASCII mov BYTE PTR [si],' ' ; Put in a space inc si ; Next buffer pos inc di ; Next code pos LOOP putlp ; Loop till done xchg si,di ; Restore regs mov ax,[bytestomove] ; Codeaddress+=bytes dumped add [code_address],ax ; endcodeline: mov ax,[isNewLine] ; Return new line flag LEAVE ; ret GetCodeLine ENDP ; ; Main disassembler ; diss PROC ENTER 256,0 ; Buffer = 256 bytes long call crlf call WadeSpace ; See if any parms jz short atindex ; No disassemble at index call ReadAddress ; Else read address jc badargs ; Get out bad args mov ax,DEFAULTBYTES ; Number of bytes to disassemble add ax,bx ; Find end of disassembly jnc okadd mov ax,-1 okadd: mov [dend],ax ; Save it as default call WadeSpace ; See if any more args jz short gotargs ; No, got args call ReadNumber ; Read the end address jc short badargs ; Out if bad args mov [dend],ax ; Save end jmp short gotargs ; We have args badargs: stc ; Error LEAVE ret atindex: mov bx,[start] ; Get the next address to disassemble mov dx,[theseg] ; mov ax,DEFAULTBYTES ; Default bytes to disassemble add ax,bx ; mov [dend],ax ; Set up end gotargs: or edx,edx ; If null selector, use CS jnz short gotseg ; mov dx,[drcs] ; gotseg: mov [code_address],bx ; Save code address for printout mov si,bx ; mov fs,dx ; ES = the seg mov [theseg],fs ; gcloop: call scankey jnz dusetadr lea di,[bp - 256] ; Get the buffer call GetCodeLine ; Get a line of text lea bx,[bp - 256] ; Print out the text call dgroupMessage call crlf cmp si,0fff0h jnc dusetadr2 cmp si,[dend] ; jc gcloop ; Loop if not test [extrabytes],-1 ; Loop if not done with dump jnz gcloop ; dusetadr: mov si,[code_address] ; mov [start],si ; clc LEAVE ret dusetadr2: sub si,si mov [code_address],si jmp dusetadr diss ENDP ; ; Disassemble one line. Used by the Reg display command ; DisOneLine PROC ENTER 256,0 ; Space for buffer push bx push dx call crlf pop dx pop bx mov ax,1 add ax,bx ; One byte to disassemble mov [dend],ax ; ( will disassemble entire instruction) mov [code_address],bx ; mov fs,dx mov si,bx mov [start],si ; Save new index mov [theSeg],fs ; dol_loop: lea di,[bp - 256] ; Get buffer call GetCodeLine ; Get a line of code lea bx,[bp -256] ; Display the line call dgroupMessage call crlf test [extrabytes],-1 ; See if more to dump jnz dol_loop ; Loop if so clc ; No errors leave ret DisOneLine ENDP END