CSC231 mytools2.inc

From dftwiki3
Revision as of 21:28, 22 October 2008 by Thiebaut (talk | contribs) (New page: <code><pre> ;;; -------------------------------------------------- ;;; -------------------------------------------------- ;;; Name: Swarnali Ahmed ;;; mytools.inc ;;; 11/06/02 Hw#7 ;;; CS...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
;;; --------------------------------------------------
;;; --------------------------------------------------
;;; Name: Swarnali Ahmed
;;; mytools.inc
;;; 11/06/02  Hw#7
;;; CSC 231
;;; PROBLEM 1
;;; 
;;;      This program includes a collection of macros and functions that
;;; will become debugging tools for use in the future programs.
;;;
;;;      It includes a collection of macros and functions in the file 
;;; mytools.inc supporting several macros expanded in the list below.
;;; 
;;; 1. displayDMem: This macro will display the contents of a double 
;;;    word in memory.
;;; 2. displayWMem, displayBMem: similar macros, but for words and bytes.
;;; 3. displayEax: This macro will display a message followed by the
;;;    contents of the EAX register.
;;; 4. displayEbx: This macro will display a message followed by the
;;;    contents of the EBX register.
;;; 5. displayEcx, displayEdx, displayEsi, displayEdi, 
;;;    displayEsp, and displayEbp. Similar macros(like eax) for the other
;;;    registers.
;;; 6. displayFlags: This macro will display a message followed
;;;    by the contents of the Flags register. This register is seldom
;;;    used as a register, instead of cases such as this one, where we
;;;    want to display it. I found the instruction pushfd which pushes
;;;    the flags register in the stack to be useful for this purpose. 
;;; 7. displayRegs message: This macro will display a message followed
;;;    by the contents of the EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP, 
;;;    and the flags register.
;;;
;;;    EXTRA CREDIT:
;;; 1. Decimal display (1/2 point):The macros above also display the 
;;;    registers and variables as unsigned decimal numbers.
;;; 2. Decimal display in signed and unsigned 2's complement format:
;;;    The macros in Question 1 above also display the variables and
;;;    registers as signed and unsigned decimal formats.
;;;    A typical output would be:
;;;    ---> eax initialized to 123
;;;    eax: 0000007B 123 +123
;;;    ---> x = FFFFFFFF 4294967295 -1
;;; 3. Flags register displayed as individual bits: Knowing that the 
;;;    carry bit is Bit 0 (least significant bit) of the eflags,
;;;    that the zero bit is Bit 6, the sign bit is Bit 7, and that the
;;;    overflow bit is Bit 11, make your display more user-friendly by
;;;    having your macro print the name of these bits as well as their value.
;;;    ---> eflags
;;;    CF=1 SF=0 ZF=1 OF=0
;;;    where CF means carry, SF sign, ZF zero, and OF overflow.
;;;
;;; 4. displayRegs2 macro display the registers in the upper right
;;;    corner of the terminal by using escape sequences.
;;;
;;;    NOTE:
;;;    NAMING CONVENTION for E-Credit :part 4: I have to macros
;;;    in my toolkit:one displays the registers in the normal cursor
;;;    which is called dispalyRegs or displayReg. The macro which 
;;;    displays the registers in the top right corner is called
;;;    displayRegs2 or displayReg2.
;;;
;;; -------------------------------------------------
;;; -------------------------------------------------

%ifndef mytools_inc
%assign mytools_inc     1

%assign SYS_EXIT	1
%assign	SYS_WRITE	4
%assign	STDOUT		1

%define displayDmem     displayDMem
%define displayWmem     displayWMem
%define displayBmem     displayBMem
%define displayReg      displayRegs
%define displayReg2     displayRegs2

;;; -----------------------------------------------------------
;;; MACROS
;;; -----------------------------------------------------------

;;; --- MACRO -----------------------------------------------
;;;	putc char
	section	.bss
_dum	resb	1
	section .text
%macro	putc	1
	push	ax
	mov	al,%1
	mov	[_dum],al
	pop	ax
	pushad
	printStr _dum,1
	popad
%endmacro
		
%macro	printStr        2		; %1 = address %2 = # of chars
        push            ecx             ; save ecx and edx so that they are
        push            edx             ; not modified by the macro
	mov     	edx,%2
	lea     	ecx,[%1]
	call    	printString
        pop             edx             ; restore edx
        pop             ecx             ; restore ecx
%endmacro

%macro  writeStr        1		; %1 = immediate string,
	section	.data
%%str	db	        %1
%%strL	equ	        $-%%str
	section	.text
	printStr        %%str, %%strL
%endmacro
	
;;;displays a register
%macro  displayaReg     2               ; %1 =message to be printed,%2 register
        push            eax
        writeStr        %1
        mov             eax,%2
        call            printDWordHex   ; print in hex
        writeStr        " "             ; space between hex and decimal
        displayDecimal  %2       
        writeStr        " "             ; space between decimal and 2's comp
        display2C       %2              ; display 2's complement
        printStr        newLine, 1
	pop             eax
%endmacro

;;prints a message and a newline
%macro  P_str_new       1               ;%1=immediate string
        writeStr        %1
   	printStr        newLine, 1
%endmacro


%macro	displayDMem     2		;display content of double word in mem 
        push	        eax		; save eax
        writeStr        %2
        mov             eax,dword[%1]
	call	        printDWordHex	; print eax in hex
        writeStr        "  "
        displayDecimal  eax
        writeStr        "  "
        display2C       eax
	printStr        newLine, 1
	pop	        eax		; get rid of eax from stack
%endmacro

%macro	displayWMem     2		; display contents of word in memory
        push	        eax		; save eax        
        writeStr        %2
        mov             ax,word[%1]
	call	        printWordHex	; print eax in hex
        movzx           eax,ax
        writeStr        "  "
        displayDecimal  eax
        writeStr        "  "
        display2C       eax
	printStr        newLine, 1
	pop	        eax		; get rid of eax from stack
%endmacro

%macro	displayBMem     2		; display contents of byte in memeory
        push	        eax		; save eax 
        writeStr        %2
        mov             al,byte[%1]
	call	        printByteHex	; print eax in hex
        writeStr        "  "
        movzx           eax,al
        displayDecimal  eax
        writeStr        "  "
        display2C       eax
	printStr        newLine, 1
	pop	        eax		; get rid of eax from stack
%endmacro


%macro	displayEax      1		; display contents of eax
        P_str_new       %1 
        displayaReg     "eax: ",eax
%endm

%macro	displayEbx      1		; display contents of ebx
        P_str_new       %1
        displayaReg     "ebx: ",ebx
%endmacro

%macro	displayEcx      1		; display contents of ecx
        P_str_new       %1
        displayaReg     "ecx: ",ecx
%endmacro

%macro	displayEdx      1		; display contents of edx
        P_str_new       %1
        displayaReg     "edx: ",edx
%endmacro

%macro	displayEsi      1		; display contents of esi
        P_str_new       %1
        displayaReg     "esi: ",esi
%endmacro

%macro	displayEdi      1		; display contents of edi
        P_str_new       %1
        displayaReg     "edi: ",edi
%endmacro

%macro	displayEbp      1		; display contents of ebp
        P_str_new       %1
        displayaReg     "ebp: ",ebp
%endmacro

%macro	displayEsp      1		; display contents of esp
        push            eax
        lea             eax,[esp+4]
        P_str_new       %1
        Onlyesp         "esp: ",eax
        pop             eax
%endmacro

;; different macro is used as esp changes values when function is called

%macro  Onlyesp         2     
        writeStr        %1
        call            printDWordHex
        writeStr        " "    
        displayDecimal  eax
        writeStr        " "    
        display2C       eax
        printStr        newLine, 1
%endmacro

%macro  display2C       1               ; %1-># to be turned to 2's Complement
        push            eax
        mov             eax,%1
        cmp             eax,0           ; compare eax to 0
        jl              %%goto 
        writeStr        "+"             ; if #>0 just print it with a + sign
        displayDecimal  eax
        jmp             %%end

%%goto: 
        neg             eax             ;if #<0,flip the bits and add 1
        writeStr        "-"             ;give a - sign
        displayDecimal  eax
%%end:
        pop             eax
%endmacro


;;display all the registers
%macro  displayRegs     1               ;%1-->given string
        push            eax
        writeStr        %1
   	printStr        newLine, 1
        call            findRegs        ;prints the strings
        pop             eax
%endmacro

%macro  displayDecimal  1               ;%1-># to expressed as decimal
        push            eax
        mov             eax,%1
        call            Decimal         ;call decimal to find and print decimal
        pop             eax      
%endmacro


%macro  displayFlags    1               ; %1-->message to be dispalyed
        P_str_new       %1
        call            makeflag        ; to display flags
%endmacro

%macro  displayBit      2               ; %1->string,%2-> flag bit
        writeStr        %1
        printStr        %2,1
        writeStr        "  "
%endmacro

;;;MACROS FOR CURSOR
;;used to movedown and save cursor,execute an instruction and restore cursor
;;back to the same position.

%macro  cursor          2
        printStr        movedown,moveLen
        printStr        save1,saveLen1            
        displayaReg2    %1,%2
        printStr        restore,saveLen1
%endmacro  

;;does the same operation as displayareg but does not have any newline.
;;cursor position is thus not changed
;;used when we want to move the cursor

%macro  displayaReg2    2               ;%1->string,%2->register
        push            eax
        writeStr        %1
        mov             eax,%2
        call            printDWordHex
        writeStr        " "    
        displayDecimal  eax
        writeStr        " "    
        display2C       eax
       	pop             eax
%endmacro

;;same job as onlyesp but no newline. Used when cursor is moved.

%macro  Onlyesp2        2
        push            eax
        writeStr        %1
        lea             eax,[%2+12]         
        call            printDWordHex
        writeStr        " "    
        displayDecimal  eax
        writeStr        " "    
        display2C       eax
	pop             eax
%endmacro


;;display registers and the flags in the top corner of the page.
%macro  displayRegs2    1
        push            eax
   
        section .data

        %%gotor1c40     db   0x1b,"[1;40H"
        %%gotoLen       equ  $-%%gotor1c40

        %%save          db   0x1b,"[s"
        %%saveLen       equ  $-%%save        

        section .text

;;moves cursor to row 1, col40
        printStr        %%gotor1c40,%%gotoLen
        printStr        %%save,%%saveLen  
        writeStr        %1
        call            findRegs2
        pop             eax
%endmacro


;;; -------------------------------------------------------------
;;; data section
;;; -------------------------------------------------------------
	section	.data
newLine	db	        0x0a		; line feed
	
;;; -------------------------------------------------------------
;;; code area
;;; -------------------------------------------------------------
	section	.text

;;; ------------------------------------------------------------
;;; printString:	 prints a string whose address is in
;;;	                 ecx, and whose total number of chars
;;;	                 is in edx.
;;; REGISTERS MODIFIED:  NONE
;;; ------------------------------------------------------------

;;;save eax and ebx so that it is not modified by the function

printString:	
        push            eax
        push            ebx
	mov     	eax,SYS_WRITE
	mov     	ebx,STDOUT
	int     	0x80

        pop             ebx
        pop             eax
	ret

;;; -----------------------------------------------------------------
;;; printDwordHex:
;;; Input: double word to be printed is in eax
;;; Output: contents of eax in hex on the screen
;;; REGISTERS MODIFIED: NONE
;;; -----------------------------------------------------------------

printDWordHex:
        push            eax
        push            ecx

        push            eax             ; save eax
        mov             cl,16           ; move upper word of eax into lower word
        shr             eax,cl          
        call            printWordHex    ; display word in hex
        pop             eax             ; get eax back
        call            printWordHex    ; display lower word in hex

        pop             ecx
        pop             eax
        ret

;;; -----------------------------------------------------------------
;;; printWordHex
;;; Input: word to be printed is in ax
;;; Ouput: contents of ax printed in hex on the screen
;;; REGISTERS MODIFIED: NONE
;;; -----------------------------------------------------------------

printWordHex:
        push            eax

        push            ax              ; save ax
        mov             al,ah           ; move upper byte to lower byte of ax
        call            printByteHex    ; display it in hex
        pop             ax              ; get ax back
        call            printByteHex    ; display al in hex
        pop             eax
        ret
        

;;; -----------------------------------------------------------------
;;; printByteHex
;;; input: byte to be printed is in al
;;; output: contents of al printed in hex on the screen
;;; REGISTERS MODIFIED: NONE
;;; -----------------------------------------------------------------

printByteHex:
        
        section .data
map     db              '0123456789ABCDEF'
byteStr db              '00'
        section .text
        push            eax
        push            ebx
        push            ecx
        push            edx

        push            eax             ; save eax
        and             al,0xF0         ; isolate upper nybble
        mov             cl,4
        shr             al,cl           ;  move it to lower nybble
        mov             ebx,0
        mov             bl,al
        mov             bl,[map+ebx]    ; xform hex into ascii
        mov             [byteStr],bl    ; store ascii in output string

        pop             eax             ; get eax back
        and             al,0x0F         ; isolate lower nybble
        mov             ebx,0
        mov             bl,al
        mov             bl,[map+ebx]    ; xform hex into ascii
        mov             [byteStr+1],bl  ; store ascii in output string

        mov             eax,SYS_WRITE   ; print ascii 2-digit string
        mov             ebx,STDOUT
        lea             ecx,[byteStr]
        mov             edx,2
        int             0x80
        
        pop             edx
        pop             ecx
        pop             ebx
        pop             eax
  
        ret


;;;------------------------------------------------------
;;;------------------------------------------------------
;;;Decimal:finds out the decimal #,stores it in a string
;;;and prints it.
;;;REGISTERS MODIFIED: NONE
;;;------------------------------------------------------
;;;------------------------------------------------------

;;;PLAN:
;;;A simple algorithm to get  the decimal is to keep dividing 
;;;by 10 the number, and accumulate the remainders until the number
;;;reaches 0. In this case you print the remainders in the reverse
;;;order than they were created, last remainder printed first...
;;;I stored thr remainder in a string in the opposite direction. 
;;;That is the first remainder is stored in the last position
;;;of the string and the last remainder is stored in the first
;;;position.The string is then printed.

Decimal:
 ;;saves all the registers so that they are not changed by the function

        push            ebx
        push            ecx
        push            edx
        push            edi

        section .bss
decstr  resb          10   
ct1     resd         1  ; to keep track of the size of the string

        section .text
        
        mov             dword[ct1],0    ; assume initially 0
        mov             edi,decstr      ; edi points to decstring
        add             edi,9           ; moved to the last element of string
        xor             edx,edx         ; clear edx for division
goback1:
        mov             ebx,10
        div             ebx
        add             edx,0x30        ; converts to ascii
        mov             byte[edi],dl   
        dec             edi
        inc             dword[ct1]
        xor             edx,edx
        cmp             eax,0
        jne             goback1       
   
        printStr        edi+1,dword[ct1]; prints the decimal #   

;;restores the registers
        pop             edi
        pop             edx
        pop             ecx
        pop             ebx

        ret


;;;----------------------------------------------------
;;;findregs:displays the contents of all the registers
;;;and the flags.
;;;REGISTERS MODIFIED:NONE
;;;----------------------------------------------------
   
findRegs:
        displayaReg     "eax: ",eax
        displayaReg     "ebx: ",ebx
        displayaReg     "ecx: ",ecx
        displayaReg     "edx: ",edx
        displayaReg     "esi: ",esi
        displayaReg     "edi: ",edi

        push            eax 
        lea             eax,[esp+12]
        Onlyesp         "esp: ",eax
        pop             eax

        displayaReg     "ebp: ",ebp
        call            makeflag
        ret

;;;------------------------------------------------------
;;;makeflag:store the bits of the flags in a string and
;;;prints it.Also shows carry bit,sign bit,overflow bit and
;;;zero bit.
;;;REGISTERS MODIFIED:NONE
;;;----------------------------------------------------------
;;;PLAN: The idea is kind of same as the decimal but this time
;;;the number is divided by 2 and the remainders stored in a 
;;;an array of size 32.Again the first remainder is stored in 
;;;the last position

makeflag:
;;saves all the registers used in the function
        push            eax
        push            ebx
        push            ecx
        push            edx
        push            edi
        pushfd
        pop             eax
        
        section .bss
dstring resb            32
ct      resd            1

        section .text
        mov             dword[ct],0     ; counter to keep track of the size
        mov             edi,dstring     ; edi points to dstring
        add             edi,31          ; edi ->last cell of dstring 
        xor             edx,edx         ; clears edx for division
goback:
        mov             ebx,2
        div             ebx
        add             edx,0x30        ; converts to a ascii
        mov             byte[edi],dl
        dec             edi
        inc             dword[ct]
        xor             edx,edx
        cmp             dword[ct],32
        jne             goback       
        
       
        writeStr        "flags: "
        printStr        edi+1,dword[ct]
        printStr        newLine, 1

        writeStr        "---->eflags"
        printStr        newLine, 1

        displayBit      "CF= ",edi+32   ; points to 0 bit,ie,last cell of dstr
        displayBit      "SF= ",edi+25   
        displayBit      "ZF= ",edi+26
        displayBit      "OF= ",edi+21
       
        printStr        newLine, 1

;;restores all the registers

        pop             edi
        pop             edx
        pop             ecx
        pop             ebx
        pop             eax
      
        ret


;;;FUNCTIONS FOR CURSOR

;;;-------------------------------------------------------------
;;;findRegs2: is the same as findRegs without the
;;;newline becaust the newline changes the cursor
;;;position.
;;;REGISTERS MODIFIED:NONE
;;;--------------------------------------------------------------

findRegs2:
        
        section .data

        save1           db    0x1b,"[s"
        saveLen1        equ   $-save1        

        restore         db    0x1b,"[u"
       
        movedown        db    0x1b,"[1B"
        moveLen         equ   $-movedown
       
        back            db    0x1b,"[40D"
        backLen         equ   $-back
        
       
        section .text
        
        printStr        restore,saveLen1

;;;carries out the following for the registers:
;;;moves the cursor down,saves the position,
;;;executes an instruction and restores the cursor position.

        cursor          "eax: ",eax
        cursor          "ebx: ",ebx
        cursor          "ecx: ",ecx
        cursor          "edx: ",edx
        cursor          "edi: ",edi
        cursor          "esi: ",esi
        cursor          "ebp: ",ebp

        printStr        movedown,moveLen
        printStr        save1,saveLen1  
        Onlyesp2        "esp: ",esp
        printStr        restore,saveLen1      

        printStr        movedown,moveLen
        printStr        save1,saveLen1  
        call            makeflag1
        printStr        restore,saveLen1

        printStr        movedown,moveLen
        printStr        back,backLen
        ret

;;;-----------------------------------------------------------
;;;makeflag1:has the same function as makeflag but the
;;;function does not have any newline.It is used to work 
;;;with cursors and newline is deleted so that the position
;;;of the cursor is not changed.
;;;REGISTERS MODIFIED:NONE
;;;---------------------------------------------------------
makeflag1:

        push            eax
        push            ebx
        push            ecx
        push            edx
        push            edi
        pushfd
        pop             eax

        section .bss
dstr1   resb           32
ct4     resd           1

        section .text
        mov             dword[ct4],0        
        mov             edi,dstr1
        add             edi,31
        xor             edx,edx
goback5:
        mov             ebx,2
        div             ebx
        add             edx,0x30
        mov             byte[edi],dl
        dec             edi
        inc             dword[ct4]
        xor             edx,edx
        cmp             dword[ct4],32
        jne             goback5       
         
       
        writeStr        "flags: "
        printStr        edi+1,dword[ct4]

        printStr        restore,saveLen1

        printStr        movedown,moveLen
        printStr        save1,saveLen1  
        writeStr        "---->eflags"
        printStr        restore,saveLen1

        printStr        movedown,moveLen
        printStr        save1,saveLen1  

        displayBit      "CF= ",edi+32
        displayBit      "SF= ",edi+25
        displayBit      "ZF= ",edi+26
        displayBit      "OF= ",edi+21



        pop             edi
        pop             edx
        pop             ecx
        pop             ebx
        pop             eax
      
        ret

%endif