The purpose of this assignment is to explore methods to represent, access, and p
ID: 3577589 • Letter: T
Question
The purpose of this assignment is to explore methods to represent, access, and process arrays in Pentium Assembler. Briefly, you are going to define an array, initialize it with random values, and determine the sum, average, minimum, and maximum of the values in the array. For this assignment, you should use a new program skeleton called utilities.asm which is available on the software course web page.
Declare a symbol called N with a value of 10 to indicate the table size; declare a table called T of size Nwhere each entry in T is 32 bits.
In addition to dump, utilities.asm also contains a function called rand8 which returns a random number in eax in the range [0..255]. Write a function called init that uses rand8 to initialize T to random values. Do not pass any arguments to init; init can refer to N and T directly. This function should not permanently modify any registers.
Write a function that calculates the sum of the contents of T. Pass the address of T to the function in eax; pass N in ebx. Return the sum in eax. Do not modify any other registers.
Write a function that calculates the minimum and maximum of the contents of T. Pass (the address of) T and (the value of) N by pushing them on the stack. Return the min in eax and the max in ebx. Do not modify any other registers.
Write a function that calculates the average (using integer arithmetic) of the contents of T. Pass arguments by passing the address of a parameter block in eax. The parameter block should contain the address of T, the value of N, followed by space for the average. Do not modify any registers.
Demonstrate that your program works for 10 values. Make sure that your program can be easily changed to accommodate other values (such as 100000) for N.
Email a copy of your .asm file(s), as well as a file containing the output messages from your program(s).
;======================================================================
TITLE Program Utilities
;======================================================================
; File: utilities.asm
; Date: 12/23/2004
; Description:
; This file contains a simple console program and includes the following
; functions:
; call dump ;show the contents of registers
; call rand8 ;return a random number in eax in the range [0..255]
; call resetTime ;sets elapsed time timer back to zero
; call reportTime ;reports elapsed time in milliseconds
; Build:
; See build.bat for a command line oriented way to assemble and link
; this program. Simply type the following to create an executable:
; masm32inml /c /coff /Cp /nologo /Zd /Zi /Fl /Fm /FR /DDebug utilities.asm
; masm32inlink /nologo /map /debug /subsystem:console utilities.obj
; or
; build utilities
;======================================================================
; (this should not require any changes)
.nolist ;turn off listing
.686 ;instructions for Pentium Pro (or better)
.model flat, stdcall ;no crazy segments!
option casemap:none ;case sensitive
;----------------------------------------------------------------------
; (insert needed external definitions here)
include masm32includewindows.inc
include masm32includemasm32.inc
include masm32includekernel32.inc
include masm32macrosmacros.asm
includelib masm32libmasm32.lib
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
;----------------------------------------------------------------------
.list ;turn on listing
.data ;insert variables below
prompt equ "<hit return>" ;prompt string
;----------------------------------------------------------------------
align 4
.code ;insert executable instructions below
main PROC ;program execution begins here
mov eax, 1 ;set regs values
mov ebx, 2
mov ecx, 3
mov edx, 4
mov esi, 5
mov edi, 6
call dump ;show contents of regs
mov eax, input(prompt) ;prompt the user
exit ;end of program
main ENDP
;----------------------------------------------------------------------
;insert additional procedures/functions here
.data
szTemp byte 16 dup (?) ;buffer for messages
szPrime byte "%08lx", 0 ;message format string
.code
;32-bit windows calling conventions:
; EBX, ESI, and EDI are preserved.
; EAX, ECX, and EDX can be freely modified.
CR = 13 ;carriage return
LF = 10 ;linefeed
;this macro outputs a newline (cr,lf)
newline MACRO
print SADD(CR,LF)
ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
show MACRO caption, value
;note: 'value' must not be in eax, ecx, or edx (because they may be
; modified by the first call).
print SADD(caption)
mov eax, value
invoke wsprintf, offset szTemp, offset szPrime, eax
print offset szTemp
ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;(some of the) eflags bits:
; ID-bit 21, OF-bit 11, SF-bit 7, ZF-bit 6, AF-bit 4, CF-bit 0
CF equ 1b ;carry flag bit
ZF equ 1000000b ;zero flag bit
SF equ 10000000b ;sign flag bit
OF equ 100000000000b ;overflow flag bit
;this function dumps the contents of the registers to the console.
;all of the caller's registers are preserved.
dump PROC
pushfd ;save eflags
pushad ;save registers (order is: eax, ecx, edx, ebx,
; esp, ebp, esi, and edi)
newline ;end line
;output registers
show " eax:", [esp+28] ;output eax
show " ebx:", [esp+16] ;output ebx
show " ecx:", [esp+24] ;output ecx
show " edx:", [esp+20] ;output edx
newline ;end line
show " esp:", [esp+12] ;output esp
show " ebp:", [esp+8] ;output ebp
show " esi:", [esp+4] ;output esi
show " edi:", [esp] ;output edi
show " eip:", [esp+36] ;output addr of next instruction
newline ;end line
;output flags
show " eflags:", [esp+32] ;output eflags
mov ebx, [esp+32] ;fetch contents of saved eflags
;CF flag
test ebx, CF ;carry set?
jz cf0 ;jump if 0
print SADD(" CF:1") ;flag is on
jmp @f ;skip over else part
cf0:
print SADD(" CF:0") ;flag is off
@@:
;ZF flag
test ebx, ZF ;zero set?
jz zf0 ;jump if 0
print SADD(" ZF:1") ;flag is on
jmp @f ;skip over else part
zf0:
print SADD(" ZF:0") ;flag is off
@@:
;SF flag
test ebx, SF ;sign set?
jz sf0 ;jump if 0
print SADD(" SF:1") ;flag is on
jmp @f ;skip over else part
sf0:
print SADD(" SF:0") ;flag is off
@@:
;OF flag
test ebx, OF ;overflow set?
jz of0 ;jump if 0
print SADD(" OF:1") ;flag is on
jmp @f ;skip over else part
of0:
print SADD(" OF:0") ;flag is off
@@:
newline ;end line
newline ;end line
;project: add code to show contents of stack here
popad ;restore pushed registers
popfd ;restore eflags
ret ;return to caller
dump ENDP
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.data
seed dword 11 ;random number generator seed (can't be 0)
.code
rand PROC
push ecx ;save modified registers
push edx
;Park Miller random number algorithm.
;Written by Jaymeson Trudgen (NaN)
;Optimized by Rickey Bowers Jr. (bitRAKE)
;
;this code is not commented because the original author did not
;comment it (not a good idea).
;
mov eax, seed
xor edx, edx
mov ecx, 127773
div ecx
mov ecx, eax
mov eax, 16807
mul edx
mov edx, ecx
mov ecx, eax
mov eax, 2836
mul edx
sub ecx, eax
xor edx, edx
mov eax, ecx
mov seed, ecx
pop edx ;restore modified registers
pop ecx
ret ;return to caller
rand ENDP
rand8 PROC
call rand ;eax will contain a 32-bit random number
and eax, 0ffh ;to yield a value in [0..255]
ret ;return to caller
rand8 ENDP
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.data
startTicks dword 0
.code
resetTime PROC
pushad ;save registers
call GetTickCount ;get starting time
mov startTicks, eax ;save start time
popad ;restore pushed registers
ret ;return to caller
resetTime ENDP
.data
timeMessage byte "elapsed time: %lu milliseconds", CR, LF, 0
timeMessageBuffer byte 256 dup (0)
.code
reportTime PROC
pushad ;save registers
call GetTickCount ;get ending time
sub eax, startTicks ;calculate elapsed time
invoke wsprintf, offset timeMessageBuffer, offset timeMessage, eax
;create message
print offset timeMessageBuffer ;output message
popad ;restore pushed registers
ret ;return to caller
reportTime ENDP
END main
;======================================================================
Explanation / Answer
Description:
; This file contains a simple console program and includes the following
; functions:
; call dump ;show the contents of registers
; call rand8 ;return a random number in eax in the range [0..255]
; call resetTime ;sets elapsed time timer back to zero
; call reportTime ;reports elapsed time in milliseconds
; call dumpXmm64 ;shows xmm registers as pairs of 64 bit fp numbers
; call dumpX87 ;shows contents of st(0)...st(7) fp registers
; Build:
; masm32inml /c /coff /Cp /nologo /Zd /Zi /Fl /Fm /FR /DDebug utilities.asm
;======================================================================
; (this should not require any changes)
.nolist ;turn off listing
.686 ;instructions for Pentium Pro (or better)
.xmm ;allow simd instructions
.model flat, stdcall ;no crazy segments!
option casemap:none ;case sensitive
;----------------------------------------------------------------------
; (insert needed external definitions here)
include masm32includewindows.inc
include masm32includemasm32.inc
include masm32includekernel32.inc
include masm32macrosmacros.asm
includelib masm32libmasm32.lib
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
;----------------------------------------------------------------------
.list ;turn listing on
;beware of the 32-bit windows calling conventions:
; EBX, ESI, and EDI are preserved.
; EAX, ECX, and EDX can be freely modified.
.data
szTemp byte 256 dup (?) ;buffer for messages
szPrime byte "%08lx", 0 ;message format string
.code
align 4
CR = 13 ;carriage return
LF = 10 ;linefeed
;this macro outputs a newline (cr,lf)
newline MACRO
print SADD(CR,LF)
ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
show MACRO caption, value
;note: 'value' must not be in eax, ecx, or edx (because they may be
; modified by the first call).
print SADD(caption)
mov eax, value
invoke wsprintf, offset szTemp, offset szPrime, eax
print offset szTemp
ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;(some of the) eflags bits:
; ID-bit 21, OF-bit 11, SF-bit 7, ZF-bit 6, AF-bit 4, CF-bit 0
CF equ 1b ;carry flag bit
ZF equ 1000000b ;zero flag bit
SF equ 10000000b ;sign flag bit
OF equ 100000000000b ;overflow flag bit
;this function dumps the contents of the registers to the console.
;all of the caller's registers are preserved.
dump PROC
pushfd ;save eflags
pushad ;save registers
; order is: eax, ecx, edx, ebx, esp, ebp, esi, and edi
newline ;end line
;output registers
show " eax:", [esp+28] ;output eax
show " ebx:", [esp+16] ;output ebx
show " ecx:", [esp+24] ;output ecx
show " edx:", [esp+20] ;output edx
newline ;end line
show " esp:", [esp+12] ;output esp
show " ebp:", [esp+8] ;output ebp
show " esi:", [esp+4] ;output esi
show " edi:", [esp] ;output edi
show " eip:", [esp+36] ;output addr of next instruction
newline ;end line
;output flags
show " eflags:", [esp+32] ;output eflags
mov ebx, [esp+32] ;fetch contents of saved eflags
;CF flag
test ebx, CF ;carry set?
jz cf0 ;jump if 0
print SADD(" CF:1") ;flag is on
jmp @f ;skip over else part
cf0:
print SADD(" CF:0") ;flag is off
@@:
;ZF flag
test ebx, ZF ;zero set?
jz zf0 ;jump if 0
print SADD(" ZF:1") ;flag is on
jmp @f ;skip over else part
zf0:
print SADD(" ZF:0") ;flag is off
@@:
;SF flag
test ebx, SF ;sign set?
jz sf0 ;jump if 0
print SADD(" SF:1") ;flag is on
jmp @f ;skip over else part
sf0:
print SADD(" SF:0") ;flag is off
@@:
;OF flag
test ebx, OF ;overflow set?
jz of0 ;jump if 0
print SADD(" OF:1") ;flag is on
jmp @f ;skip over else part
of0:
print SADD(" OF:0") ;flag is off
@@:
newline ;end line
newline ;end line
;project: add code to show contents of stack here
popad ;restore pushed registers
popfd ;restore eflags
ret ;return to caller
dump ENDP
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.data
seed dword 11 ;random number generator seed (can't be 0)
.code
rand PROC
push ecx ;save modified registers
push edx
;Park Miller random number algorithm.
;Written by Jaymeson Trudgen (NaN)
;Optimized by Rickey Bowers Jr. (bitRAKE)
;
;this code is not commented because the original author did not
;comment it (not a good idea).
;
mov eax, seed
xor edx, edx
mov ecx, 127773
div ecx
mov ecx, eax
mov eax, 16807
mul edx
mov edx, ecx
mov ecx, eax
mov eax, 2836
mul edx
sub ecx, eax
xor edx, edx
mov eax, ecx
mov seed, ecx
pop edx ;restore modified registers
pop ecx
ret ;return to caller
rand ENDP
rand8 PROC
call rand ;eax will contain a 32-bit random number
and eax, 0ffh ;to yield a value in [0..255]
ret ;return to caller
rand8 ENDP
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.data
startTicks dword 0
.code
resetTime PROC
pushad ;save registers
call GetTickCount ;get starting time
mov startTicks, eax ;save start time
popad ;restore pushed registers
ret ;return to caller
resetTime ENDP
.data
timeMessage byte "elapsed time: %lu milliseconds", CR, LF, 0
timeMessageBuffer byte 256 dup (0)
.code
reportTime PROC
pushad ;save registers
call GetTickCount ;get ending time
sub eax, startTicks ;calculate elapsed time
invoke wsprintf, offset timeMessageBuffer, offset timeMessage, eax
;create message
print offset timeMessageBuffer ;output message
popad ;restore pushed registers
ret ;return to caller
reportTime ENDP
;======================================================================
.data
align 8
var real8 0.0 ;temp storage for 64-bit fp values
fpStatus dword 0 ;to save mxcsr
fpFormat byte "%-20s", 0 ;message format string
fpTemp byte 256 dup (0) ;buffer for messages
;define masks for (some of the) mxcsr register bits: ZM-bit 2
ZM equ 100b ;carry flag bit
OM equ 1000b ;overflow flag bit
UM equ 10000b ;underflow flag bit
RC1M equ 10000000000000b ;rounding control 1 flag bit
RC2M equ 100000000000000b ;rounding control 2 flag bit
.code
;this macro prints a caption string and the fp contents of one of the
; xmm registers. each xmm reg contains 2 fp numbers.
;note: 'xmReg' must be xmm0..xmm7
showXmm64 MACRO caption, xmReg
print SADD(" ") ;print space
print SADD(caption) ;print the caption string
print SADD(" ") ;print space
movhpd var, xmReg ;save the hi 64 bits
invoke FloatToStr, var, addr szTemp ;convert to float
mov eax, offset szTemp
invoke wsprintf, offset fpTemp, offset fpFormat, eax
print offset fpTemp ;print float value
print SADD(" ") ;print space
movlpd var, xmReg ;save the lo 64 bits
invoke FloatToStr, var, addr szTemp ;convert to float
print offset szTemp ;print float value
newline ;end line
ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;this function dumps the contents of the xmm0..xmm7 registers to the console.
;all of the caller's registers are preserved.
dumpXmm64 PROC
stmxcsr fpStatus ;save the fp status reg
pushfd ;save eflags
pushad ;save registers
newline ;end line
;
showXmm64 "xmm0:", xmm0 ;show fp contents of xmm0
showXmm64 "xmm1:", xmm1 ;show fp contents of xmm1
showXmm64 "xmm2:", xmm2 ;show fp contents of xmm2
showXmm64 "xmm3:", xmm3 ;show fp contents of xmm3
showXmm64 "xmm4:", xmm4 ;show fp contents of xmm4
showXmm64 "xmm5:", xmm5 ;show fp contents of xmm5
showXmm64 "xmm6:", xmm6 ;show fp contents of xmm6
showXmm64 "xmm7:", xmm7 ;show fp contents of xmm7
;
show " mxcsr:", fpStatus ;output eflags
;RC field (2 bits)
test fpStatus, RC2M ;check the high order bit first
jz rc20
print SADD(" RC:0")
jmp @f
rc20:
print SADD(" RC:1")
@@:
test fpStatus, RC1M ;check the low order bit first
jz rc10
print SADD("0")
jmp @f
rc10:
print SADD("1")
@@:
;UM flag
test fpStatus, UM ;underflow set?
jz um0 ;jump if 0
print SADD(" UM:1") ;flag is on
jmp @f ;skip over else part
um0:
print SADD(" UM:0") ;flag is off
@@:
;OM flag
test fpStatus, OM ;overflow set?
jz om0 ;jump if 0
print SADD(" OM:1") ;flag is on
jmp @f ;skip over else part
om0:
print SADD(" OM:0") ;flag is off
@@:
;ZM flag
test fpStatus, ZM ;divide-by-zero set?
jz zm0 ;jump if 0
print SADD(" ZM:1") ;flag is on
jmp @f ;skip over else part
zm0:
print SADD(" ZM:0") ;flag is off
@@:
newline ;end line
;
popad ;restore pushed registers
popfd ;restore eflags
ldmxcsr fpStatus ;restore the fp status reg
ret ;return to caller
dumpXmm64 ENDP
;======================================================================
.data
;the following table must be this size and this order
fpState dword 7 dup(0)
fpR0 real10 0.0
fpR1 real10 0.0
fpR2 real10 0.0
fpR3 real10 0.0
fpR4 real10 0.0
fpR5 real10 0.0
fpR6 real10 0.0
fpR7 real10 0.0
;check the table size
fpSize = $ - fpState
if fpSize ne 108
echo invalid table size
.err
endif
.code
;this macro prints a caption string and the fp contents of one of the
; x87 registers.
showFP64 MACRO caption, fpReg
print SADD(" ") ;print space
print SADD(caption) ;print the caption string
print SADD(" ") ;print space
fld fpReg ;load 80 bit fp reg val
fstp var ;store and pop as 64 bit fp val
invoke FloatToStr, var, addr szTemp ;convert to float
print offset szTemp ;print float value
newline ;end line
ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
dumpX87 proc
pushfd ;save eflags
pushad ;save registers
fsave fpState ;save x87 fp state
;
newline ;end line
;output all of the x87 fp register stack
showFP64 "st(0): ", fpR0
showFP64 "st(1): ", fpR1
showFP64 "st(2): ", fpR2
showFP64 "st(3): ", fpR3
showFP64 "st(4): ", fpR4
showFP64 "st(5): ", fpR5
showFP64 "st(6): ", fpR6
showFP64 "st(7): ", fpR7
;
frstor fpState ;restore x87 fp state
popad ;restore pushed registers
popfd ;restore eflags
ret ;return to caller
dumpX87 endp
;======================================================================
end
;======================================================================
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.