Difference between revisions of "CSC231 mytools2.inc"
Line 1: | Line 1: | ||
− | <source lang=" | + | <source lang="asm"> |
;;; -------------------------------------------------- | ;;; -------------------------------------------------- | ||
;;; -------------------------------------------------- | ;;; -------------------------------------------------- |
Revision as of 14:37, 20 September 2014
;;; --------------------------------------------------
;;; --------------------------------------------------
;;; 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