Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

In this exercise you will learn how to set up a Visual Studio project for 64-bit assembly language development. You will make modifications to the

In this exercise you will learn how to set up a Visual Studio project for 64-bit assembly language development. You will make modifications to the setup_vs_64.asm file to complete the ReadString procedure. The instructions for the modifications you need to make are contained within the source code itself, in the ReadString PROC (line 180). Turn in your modified .asm file when done.

You will be using a Microsoft procedure called ReadConsoleA for this assignment.

COMMENT ! This information is from section 5.5.3 in the book.

Microsoft follows a consistent scheme for passing parameters and calling procedures in 64-bit programs known as the Microsoft x64 Calling Convention. This convention is used by C/C++ compilers, as well as by the Windows Application Programming Interface (API). The only times you need to use this calling convention is when you either call a function in the Windows API, or you call a function written in C or C++. Here are some of the basic characteristics of this calling convention: 1. The CALL instruction subtracts 8 from the RSP (stack pointer) register, since addresses are 64-bits long. 2. The first four parameters passed to a procedure are placed in the RCX, RDX, R8, and R9, registers, in that order. If only one parameter is passed, it will be placed in RCX. If there is a second parameter, it will be placed in RDX, and so on. Additional parameters are pushed on the stack, in left-to-right order. 3. It is the callers responsibility to allocate at least 32 bytes of shadow space on the runtime stack, so the called procedures can optionally save the register parameters in this area. 4. When calling a subroutine, the stack pointer (RSP) must be aligned on a 16-byte boundary (a multiple of 16). The CALL instruction pushes an 8-byte return address on the stack, so the calling program must subtract 8 from the stack pointer, in addition to the 32 it already subtracts for the shadow space. We will soon show how this is done in a sample program. !

;------------------------------------------------ ; Prototypes ;------------------------------------------------ ; Prototypes for procedures in this source file GetHandles proto Crlf proto StrLength proto RemoveCrlf proto ReadString proto WriteString proto WriteDec proto WriteHex proto

; Windows API prototypes ExitProcess proto ReadConsoleA proto WriteConsoleA proto GetStdHandle proto

;------------------------------------------------ ; Constants ;------------------------------------------------ BufferSize = 80 endl EQU <0dh,0ah> ; end of line sequence STD_INPUT_HANDLE EQU -10 STD_OUTPUT_HANDLE EQU -11 ; predefined Win API constant

;------------------------------------------------ ; Data segment ;------------------------------------------------ .data consoleInHandle QWORD ? ; handle to standard input device consoleOutHandle QWORD ? ; handle to standard output device bytesWritten QWORD ? ; number of bytes written bytesRead QWORD ? buffer BYTE BufferSize DUP(0),0

msg1 BYTE "Please enter some text",0

sum QWORD 0

;------------------------------------------------ ; Code segment ;------------------------------------------------ .code main proc sub rsp, 8 ; align stack after function call to main

; Get the standard input and output handles call GetHandles

; Really big integers mov rax, 0ABCDEFAFFFFFFFFh ; 64-bit immediate operand add rax, 10h mov sum, rax call WriteHex call Crlf call WriteDec call Crlf

; Output a string to the console mov rdx, OFFSET msg1 call WriteString call Crlf

; Read from a string from the console ; You will need to fill in the code for this procedure. mov rdx, OFFSET buffer ; buffer offset mov r8, BufferSize ; max characters allowed call ReadString

; Write out the text that was read in mov rdx, OFFSET buffer ; buffer offset call WriteString call Crlf

mov ecx,0 ; Indicates non-error exit status call ExitProcess

main endp

;---------------------------------------------------------------- GetHandles PROC ;---------------------------------------------------------------- ; get the standard input and output handles sub rsp,28h ; set aside shadow space + align stack pointer mov rcx,STD_INPUT_HANDLE call GetStdHandle mov [consoleInHandle],rax mov rcx,STD_OUTPUT_HANDLE call GetStdHandle mov [consoleOutHandle],rax add rsp,28h ; restore stack ret GetHandles ENDP

;---------------------------------------------------------------- Crlf PROC USES rax rcx rdx r8 r9 ;---------------------------------------------------------------- .data CrlfStr BYTE endl .code sub rsp, (8 +32 + 16) ; align stack, shadow space, one parameter plus alignment mov rcx,consoleOutHandle mov rdx,OFFSET CrlfStr ; string pointer mov r8, 2 ; length of string lea r9,bytesWritten mov qword ptr [rsp + 4 * SIZEOF QWORD], 0 ; (reserved parameter, set to zero) call WriteConsoleA add rsp, (8 + 32 +16) ret Crlf ENDP

;---------------------------------------------------------------- StrLength PROC USES rsi ; Pointer to string passed in RDX ; Length returned in RAX ; Finds the length of a string by looking for the NULL character ;---------------------------------------------------------------- mov rsi, rdx mov rax, 0 L1: cmp BYTE PTR [rsi], 0 je L2 inc rsi inc rax jmp L1

L2: ret StrLength ENDP

;---------------------------------------------------------------- RemoveCrlf PROC USES rsi ; Pointer to string passed in RDX ; Replaces the 0dh character with zero (NULL) ;---------------------------------------------------------------- mov rsi, rdx ; find the 0dh character, replace with zero L1: cmp BYTE PTR [rsi], 0dh je L2 cmp BYTE PTR [rsi], 0 je L3 inc rsi jmp L1

L2: mov BYTE PTR [rsi], 0 ; put null character there L3: ret RemoveCrlf ENDP

;---------------------------------------------------------------- ReadString PROC USES rcx r9 ; Pointer to buffer passed in RDX ; Buffersize in R8 ;---------------------------------------------------------------- sub rsp, 8 ; align stack after function call

; You will use the ReadConsoleA procedure to read in a string. ; You will use the x64 Calling Convention to pass parameters to it. ; It expects to receive: standard in handle, pointer to buffer, buffer size, ; pointer to bytes read, and an unused parameter.

; call ReadConsoleA

add rsp, 8 ; From the alignment ret ReadString ENDP

;---------------------------------------------------------------- WriteString PROC USES rax rcx r8 r9 ; Pointer to buffer passed in RDX ;---------------------------------------------------------------- sub rsp, 8 ; align after procedure call

call StrLength ; returns length of string in RAX

sub rsp, 32 ; create shadow space for 4 parameters sub rsp, 16 ; one parameter on stack plus alignment mov rcx,consoleOutHandle ; string pointer in RDX mov r8, rax ; length of string lea r9,bytesWritten mov qword ptr [rsp + 4 * SIZEOF QWORD], 0 ; (reserved parameter, set to zero) call WriteConsoleA add rsp, (32 + 16) ; restore stack after procedure call

add rsp, 8 ; Restore the alignment offset ret WriteString ENDP

;----------------------------------------------------- WriteDec PROC USES rax rbx rcx rdx rdi ; Expects the number to be in RAX ; Writes an unsigned 64-bit decimal number to ; the console window. ; This is a mofified version of what was in the ; Irvine library. ;------------------------------------------------------ .data ; There will be as many as 20 digits. WDBUFFER_SIZE = 24

bufferL BYTE WDBUFFER_SIZE DUP(?),0

.code sub rsp, 8 ; align after procedure call mov rcx,0 ; digit counter mov rdi, OFFSET bufferL add rdi, (WDBUFFER_SIZE - 1) mov rbx,10 ; decimal number base

WI1:mov rdx,0 ; clear dividend to zero div rbx ; divide RAX by the radix

xchg rax,rdx ; swap quotient, remainder or al, 30h ; convert AL to ASCII mov [rdi],al ; save the digit dec rdi ; back up in buffer xchg rax,rdx ; swap quotient, remainder

inc rcx ; increment digit count or rax,rax ; quotient = 0? jnz WI1 ; no, divide again

; Display the digits WI3: inc rdi mov rdx, rdi call WriteString

WI4: add rsp, 8 ; Restore the alignment offset ret WriteDec ENDP

;---------------------------------------------------------------- WriteHex PROC USES rax rbx rcx rdx rsi rdi r8 r9 r11 ; Integer value received in rax. ; Writes integer value as a hex number. ; Leading zeroes are skipped. ;---------------------------------------------------------------- hexLetterStart = 'A' - 0Ah .data hexString BYTE 16 DUP(?),0 intValue QWORD 0 .code sub rsp, 8 ; align after procedure call ; clear the hex string buffer mov rcx, 16 mov rdi, OFFSET hexString cld mov al, 0 rep stosb

; check to see if zero, if so just print that mov rdx, OFFSET hexString cmp rax, 0 jnz notZero mov BYTE PTR [rdx], 30h call WriteString add rsp, 8 ; Restore the alignment offset ret

notZero: mov rdi, OFFSET hexString

; the number is little endian, reverse order ; by using stack mov intValue, rax mov rcx, 8 ; qword is 4 bytes in length lea rsi, intValue L0: movzx rax, BYTE PTR [rsi] push rax inc rsi loop L0

mov rcx, 8 ; dword is 4 bytes in length L1: ; convert the first 4 bits of this byte to an ASCII number pop rbx mov al, bl shr al, 4 cmp al, 0Ah jb L2 add al, hexLetterStart jmp L3 L2: or al, 30h L3: mov [rdi], al

; convert the next 4 bits of this byte to an ASCII number inc rdi mov al, bl and al, 0Fh

cmp al, 0Ah jb L4 add al, hexLetterStart jmp L5 L4: or al, 30h L5: mov [rdi], al

inc rdi loop L1

; now display the resulting string mov rcx, 16 mov rdx, OFFSET hexString mov bl, 0 L6: ; check to see if we have encountered any nonzero characters cmp bl, 0 jne L7 ; if not skip over leading zeroes cmp BYTE PTR [rdx], 30h je L8 mov bl, 1 ; set flag for nonzero character L7: push rcx push rdx sub rsp, (32 + 16) ; shadow space plus one parameter plus align mov rcx, consoleOutHandle ; string pointer in RDX mov r8, 1 ; length of string lea r9, bytesWritten mov qword ptr [rsp + 4 * SIZEOF QWORD], 0 ; (reserved parameter, set to zero) call WriteConsoleA add rsp, (32 + 16) pop rdx pop rcx

L8: inc rdx loop L6

add rsp, 8 ; Restore the alignment offset ret WriteHex ENDP

end

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Big Data, Mining, And Analytics Components Of Strategic Decision Making

Authors: Stephan Kudyba

1st Edition

1466568704, 9781466568709

More Books

Students also viewed these Databases questions