Question
Compile and execute the existing Assembly code on the left side of the screen. The following is the code that should be displayed: (Complineonline, n.d.)
Compile and execute the existing Assembly code on the left side of the screen. The following is the code that should be displayed: (Complineonline, n.d.)
%macro Print_Var 2 ; Print the variable-name mov edi, %1 ; STRING [edi] :: Address of the string to print mov esi, 1 ; LENGTH [esi] :: Length of the string call _Our_Print ; Print the EQUAL-SIGN mov edi, EQUAL_SIGN ; STRING [edi] :: Address of the string to print mov esi, EQUAL_SIGN_LEN ; LENGTH [esi] :: Length of the string call _Our_Print ; Print the HEXADECIMAL indicator (0x) mov edi, HEX_IND ; STRING [edi] :: Address of the string to print mov esi, HEX_IND_LEN ; LENGTH [esi] :: Length of the string call _Our_Print ; Convert the given byte to a character-string mov edi, [%2] ; Address of BYTE [edi] :: Byte to convert to string mov esi, VAR_STR ; STRING [esi] :: Address of the string mov edx, VAR_STR_LEN ; LENGTH [edx] :: Length of the string call _Byte_to_String ; Print the converted byte integer mov edi, VAR_STR ; STRING [edi] :: Address of the string to print mov esi, 2 ; LENGTH [esi] :: Length of the string call _Our_Print ; Print an ASCII carriage return (CR) control-character mov edi, CR ; STRING [edi] :: Address of the string to print mov esi, 1 ; LENGTH [esi] :: Length of the string call _Our_Print ; Print an ASCII newline (LF) control-character mov edi, LF ; STRING [edi] :: Address of the string to print mov esi, 1 ; LENGTH [esi] :: Length of the string call _Our_Print %endmacro %macro Exit_Program 0 %ifdef _WINDOWS_ push 0 call _ExitProcess@4 %else mov eax, 1 ; System call number (sys_exit) int 0x80 ; Call kernel %endif %endmacro ; ***************************************************************************** ; MAIN: Demo ; PURPOSE: Main entry-point to the EXECUTABLE. ; NOTES: Equivalent to C language main(argc, argv) ; ***************************************************************************** _START_: ; Tell linker entry point ; ======== Display current values ======== Display_variables: %ifdef DEBUG ; Instructor Question 1: What are we doing here? Print_Var W_CHAR, W Print_Var X_CHAR, X Print_Var Y_CHAR, Y Print_Var Z_CHAR, Z Print_Var N_CHAR, N CALL_Our_Print CR, 1 CALL_Our_Print LF, 1 %endif ; ======== Calculate W * Y ======== Multiply_WY: mov eax, 0 ; Initialize eax prior to using it mov ebx, 0 ; Initialize ebx prior to using it mov esi, W ; Move the address of W into esi mov eax, [esi] ; Move the value at W into eax mov esi, Y ; Move the address of X into esi mov ebx, [esi] ; Move the value at Y into ebx imul eax, ebx ; Multiply: X * Y mov [RESULT], eax ; Store the result Display_WY_product: Print_Msg MSG_A0, LEN_A0, RESULT ; ======== Calculate X << N ======== Shift_W_left_by_N: mov eax, 0 ; Initialize eax prior to using it mov ecx, 0 ; Initialize ecx prior to using it mov esi, W ; Move the address of W into esi mov eax, [esi] ; Move the value at W into eax mov esi, N ; Move the address of N into esi mov ecx, [esi] ; Move the value at N into cl register shl eax, cl ; Shift W << N mov [RESULT], eax ; Store the result Display_W_left_shift: Print_Msg MSG_A1, LEN_A1, RESULT ; Instructor Question 1: Why is (W * Y) equal to (W << N) ? ; ======== Calculate Z / Y ======== Divide_ZY: mov edx, 0 ; Zero-out edx because idiv treats it as high bits above eax! mov eax, 0 ; Initialize eax prior to using it mov ecx, 0 ; Initialize ecx prior to using it mov esi, Z ; Move the address of Z into esi mov eax, [esi] ; Move the value at Z into eax mov esi, Y ; Move the address of Y into esi mov ecx, [esi] ; Move the value at Y into ecx div ecx ; Divide: Z / Y mov [RESULT], eax ; Store the result Display_ZY_quotient: Print_Msg MSG_B0, LEN_B0, RESULT ; ======== Calculate N >> Z ======== Shift_Z_right_by_N: mov eax, 0 ; Initialize ebx prior to using it mov ecx, 0 ; Initialize ecx prior to using it mov esi, Z ; Move the address of Z into esi mov eax, [esi] ; Move the value at Z into eax mov esi, N ; Move the address of N into esi mov ecx, [esi] ; Move the value at N into ecx register shr al, cl ; Shift: N >> Z mov [RESULT], eax ; Store the result Display_Z_right_shift: Print_Msg MSG_B1, LEN_B1, RESULT ; Instructor Question 2: Why is (Z / Y) equal to (N >> Z) ? _EXIT_: Exit_Program ; END OF MAIN() ; ***************************************************************************** ; PROC: Byte_to_String(BYTE, STRING, LENGTH) ; PURPOSE: Convert byte integer into its ASCII (printable) equivalent. ; INPUT: BYTE [edi] :: Byte to convert to string ; STRING [esi] :: Address of the string ; LENGTH [edx] :: Length of the string ; OUTPUT: eax :: Returns 0 if successful, else -1. If successful, then the ; Contents of the given string [ecx] contains the convert integer. ; USES: eax :: Contains high/low-order nibble of byte to convert ; NOTES: ; ***************************************************************************** _Byte_to_String: ; Start of procedure definition push eax ; Save off the current contents of the regs push ebx push ecx cmp edx, 0x3 ; Make sure that given string is large enough jl Bad_B2S ; It's not, so do not perform the operation mov eax, edi ; Byte to convert to string mov ecx, esi ; Get the address of the string buffer and eax, 0x000000F0 ; Mask off the high-order nibble shr eax, 4 ; Push the high-order nibble to the low-order nibble ; Instructor Question 3: Why do we do this? add eax, '0' ; mov [ecx], eax ; Write the converted high-order nibble to the string add ecx, 1 ; Move the pointer to the next character position in the string mov eax, edi ; Byte to convert to string and eax, 0x0000000F ; Mask off the low-order nibble add eax, '0' ; mov [ecx], eax ; Write the converted low-order nibble to the string add ecx, 1 ; Move the pointer to the next character position in the string mov eax, 0 ; Move a ZERO into eax letting the caller know that we were SUCCESSFUL mov [ecx], eax ; Put a trailing zero in the string. jmp Done_B2S ; We're done -- restore the registers used and return Bad_B2S: mov eax, -1 ; Move a ZERO into eax letting the caller know that we were unSUCCESSFUL Done_B2S: pop eax ; Restore the previous contents of the regs pop ebx pop ecx ret ; End of procedure definition
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started