COEN311 (Winter 2021) Homework #4 Solutions Problem 1) Given following function, where the variables x and f are positive 16-bit and 32-bit memory references, respectively. f = [x÷(x-4)2] + 8 Write an x86 assembly program that first reads the input x from memory, checks its validity by verifying that x ≠ 4, and then if this condition is satisfied, it performs the function and writes the result in f ; otherwise it outputs an error message on the screen in the form of a string “Division Error”. section .data msg db ‘Division Error’ section .bss f resd 1 ; Declare 32 bit for f x resw 1 ; Declare 16 bit for x section .text global _start start_: mov eax, [x] ; Place x into EAX cmp eax, 4 ; check if x = 4 je ErrorMsg ; Display error message sub eax, 4 ; EAX = (x – 4) imul eax mov ebx,eax mov eax,[x] idiv ebx add eax, 8 mov [f], eax jmp End ErrorMsg: mov ah, 0x02 mov ecx, 0 MsgLoop: mov dl, [msg+ecx] int 0x21 inc ecx cmp ecx, 14 jne MsgLoop End: hlt ; ; ; ; ; ; ; ; ; ; ; ; ; ; EDX:EAX = EAX ✕ EAX (x–4)2 in EAX EBX = (x–4)2 Place x into EAX EAX = Q[EDX:EAX ÷ EBX] = Q[x ÷(x–4)2] EAX = EAX + 8 = [x÷(x–4)2]+ 8 Place the result at memory address f Jump over to End Prepare for character output Set counter to 0 Storing one character of msg in DL Call ISR to display character in DL Increment counter Check if counter = 14 (end of string) Loop back for next character to output Problem 2) Write an x86 assembly macro mult that implements unsigned multiplication of two 16 bit numbers (n1, n2) stored in memory and produces a product (prod) of 32 bits. ; ; ; input: output: %1: n1 (first number) %2: n2 (second number) %3: prod (product = n1 * n2) %macro mult 3 mov eax, 0 mov ebx, [%1] mov ecx, [%2] loop: cmp ebx, 0 je result add eax, ecx dec ebx jmp loop result: mov [%3], eax %endmacro ; main program section .bss n1 resw 1 n2 resw 1 prod resd 2 section .text global _start _start: .. .. .. .. mult n1, n2, prod .. .. .. .. hlt ; ; ; ; ; ; ; ; ; initialize prod (eax) = 0 read input n1 in ebx (multiplicand) read input n2 in ecx (multiplier) check if multiplicand = 0 write resulting product add multiplier decrement multiplicand loop back for next iteration store result into output prod Problem 3) a) Write an x86 subroutine mean to calculate the mean M of a given list of N 16 bit numbers. Parameters are passed using the stack ;input: array address: 4 bytes at ESP+4 after subroutine call ; array size: 2 bytes at ESP+8 after subroutine call ;output: mean: 2 bytes at ESP+8 mean: loop1: mov mov mov mov add add loop mov idiv push add ret edx, [esp+4] cx, [esp+8] ax, 0 bx, [edx] ax, bx edx, 2 loop1 dx, 0 [esp+8] ax esp, 2 ; ; ; ; ; ; ; ; ; ; ; retrieve array address from stack retrieve array size from stack clear AX (sum) retrieve array[i] add array[i] to sum increment array address loop if CX ≠ 0 prepare for div compute mean (sum ÷ array size) push mean on stack restore ESP to return address b) Write an x86 subroutine variance to calculate the variance 2 of a given list of N 16 bit numbers. Parameters are passed using the stack. ;input: array address: 4 bytes at ESP+6 after subroutine call ; array size: 2 bytes at ESP+10 after subroutine call ; mean: 2 bytes at ESP+4 after subroutine call ;output: variance: 2 bytes at address ESP-6 after ret to main ;intermediate storage: sum: on top of stack during the subroutine variance: loop2 mov mov mov push mov sub imul add add loop pop mov idiv push add ret edx, [esp+6] cx, [esp+10] ax, 0 ax ax, [edx] ax, [esp+6] ax [esp], ax edx, 2 loop2 ax dx, 0 [esp+10] ax esp, 2 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; retrieve array address from stack retrieve array size from stack sum = 0 push sum on stack retrieve array[i] array[i] – M (mean M from stack) square (array[i] – M) add (array[i] – M)2 to sum increment array address loop if CX ≠ 0 pop sum from stack to AX prepare for div compute mean (sum ÷ array size) push variance on stack restore ESP to return address c) Write the main x86 program that calculates the variance of the given array of N 16-bit numbers by calling the subroutines mean and variance ; main program section .data size dw 100 section .bss array resw 100 var resw 1 section .text global _start _start: push [size] push array call mean push [esp-6] ; array size ; array space for 100 16-bit integers ; variance ; push size into stack ; push address of array ; upon return mean value at ESP-6 ; push mean to stack call variance ; upon return variance value at ESP-6 sub pop esp, 6 [var] ; reposition ESP at variance value on stack ; pop variance value into memory loc. var add esp, 12 ; reset ESP to its initial value hlt