No ACL setup yet! Denying access to everyone.
en:edu:zmitac:s1:apl:lab:lab3

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:edu:zmitac:s1:apl:lab:lab3 [2024/11/27 14:49] – [Laboratory 3] ktokarzen:edu:zmitac:s1:apl:lab:lab3 [2024/12/03 14:40] (current) – [Tasks to be done during laboratory] ktokarz
Line 1: Line 1:
 ====== Programming in Assembler Laboratory ====== ====== Programming in Assembler Laboratory ======
 ===== Laboratory 3 ===== ===== Laboratory 3 =====
-DLL functions calling and passing parameters.+Addressing modes.
 ===== The aim of the exercise ===== ===== The aim of the exercise =====
-The aim of the exercise is to learn about x64 processor addressing modes. The design of the project assumes the possibility of calling library functions written in assembler from the application level and shows the correct configuration of the environment enabling debugging code to assembler level, observing the state of registers and flags of the processor or data memory areas. Another aim of the exercise is to learn the methods of arguments passing to the procedures and techniques for measuring machine code execution time. +The aim of the exercise is to learn about different addressing modes you can use to access the data in the memory. 
-<note>Calling assembler functions from high-level language programs is currently the most common assembler use.</note> +
-<note>The configuration and solution creation process is identical to the one presented in exercise 2. The main program should be written in C++ and dynamically linked library in assembler.</note>+
 ===== The example code ===== ===== The example code =====
-The following code is divided into two parts. The C++ part calls the functions in a dynamically linked library. One function, called FindChar_1() searches for the "J" character in a string. The string is defined inside the DLL. Another function ReadTime_1() measures the execution time of the first function.+The following code is divided into two parts. The C++ part calls the functions in a dynamically linked library. DLL contains three different functions copying the content of the source string to three destination strings using different addressing modes. One function, called CopyString_base() uses a base addressing mode. The second function CopyString_base_index() uses base + index addressing mode. The last one CopyString_base_disp() uses base + displacement.
  
-C++ file+The strings are defined inside the DLL. 
  
-<code>+**C++ file** 
 + 
 +<code c>
 #include <iostream> #include <iostream>
 #include <windows.h> #include <windows.h>
Line 22: Line 23:
     std::cout << "Hello World!\n";     std::cout << "Hello World!\n";
     dllHandle = LoadLibrary(TEXT("JaAsm.dll"));     dllHandle = LoadLibrary(TEXT("JaAsm.dll"));
-    std::cout << procedura();+     
 +    MyProc Copy_base = (MyProc)GetProcAddress(dllHandle, "CopyString_base"); 
 +    MyProc Copy_index = (MyProc)GetProcAddress(dllHandle, "CopyString_base_index"); 
 +    MyProc Copy_disp = (MyProc)GetProcAddress(dllHandle, "CopyString_base_disp");
  
-    MyProc FindChar = (MyProc)GetProcAddress(dllHandle, "FindChar_1"); +    Copy_base(); 
-    MyProc ReadTime = (MyProc)GetProcAddress(dllHandle, "ReadTime_1"); +    Copy_index(); 
- +    Copy_disp();
-    char szString[] = { 'A','G','I','K','S','Z','J', 0xFF }; // string definition  +
-    printf("FindChar_1 %s\n", (FindChar() == 1 ? "Found J" : "Not Found J")); +
-    printf("Processing time: %i\n", ReadTime());+
 } }
 </code> </code>
  
-Assembler dll file.+**Assembler dll file.** 
 <code> <code>
-;**************************************************************************** 
-;   String definition 
-;**************************************************************************** 
 .data  .data 
-DataString DB 'AGIKSZJ', 0FFH; string definition  +SourceDataString DB 'AGIKSZJ', 0FFH ; source string definition 
 +DestinBaseString DB '       ', 0; buffer for destination string, null terminated 
 +DestinIndexString DB '       ', 0; buffer for destination string, null terminated 
 +DestinDisplString DB '       ', 0; buffer for destination string, null terminated
  
 .code .code
-;**************************************************************************** + 
-;   Procedure to find the character in a string +;****************************************************************************  
-;   No input parameters, result is 1 if character found, 0 otherwise +;   This function uses base addressing mode 
-;**************************************************************************** +;****************************************************************************  
-FindChar_1 PROC  +CopyString_base PROC  
-    PUSH RSI +    PUSH RSI                    ; RSI, RDI are non-volatile registers 
-    LEA RSI, DataString      ; load the address of variable 'DataString' into reg. ESI  +    PUSH RDI 
-    MOV AL, 'J'              ; load the code of character 'J' into reg. AH  +    LEA RSI, SourceDataString   ; load address of variable 'SourceDataString' into reg. RSI 
-Check_End:  +    LEA RDI, DestinBaseString   ; load address of variable 'DestinBaseString' into reg. RDI 
-    CMP BYTE PTR [RSI], 0FFH ; is it the end of a string (special character FF)?  +    MOV AL, 0FFH     ; load the ending character 'FF' into reg. AL 
-    JE Not_Find              ; found end character (guard)  +Copy_Loop:  
-    CMP AL, [RSI]            ; compare a character with chosen char of string 'DataString'  +    CMP BYTE PTR [RSI], AL  ; is it the end of a string (special character FF)?  
-    JE Got_Equal             ; character found!  +    JE String_End     ; found end character (guard)  
-    ADD RSI, 1               ; increment an offset +    MOV AH, [RSI]     ; take one character from source string 
-    JMP Check_End            ; search loop  +    MOV [RDI], AH               ; put it into  destination string 
-Got_Equal:  +    ADD RSI, 1         ; increment index registers 
-    MOV DL, [RSI]            ; load found char into DL  +    ADD RDI, 1 
-    JMP Done  +    JMP Copy_Loop     ; jump to beginning of a loop  
-Not_Find:  +String_End:  
-    MOV RAX,0                ; character not found +    POP RDI
     POP RSI     POP RSI
-    RET                      ; return from procedure  +    RET             ; return form procedure 
-Done:  +CopyString_base ENDP ; end of CopyString_base 
-    MOV RAX,1                ; character found+ 
 +;****************************************************************************  
 +;   This function uses base + index addressing mode 
 +;****************************************************************************  
 +CopyString_base_index PROC  
 +    PUSH RSI                    ; RSI, RDI are non-volatile registers 
 +    PUSH RDI 
 +    LEA RSI, SourceDataString   ; load address of variable 'SourceDataString' into base reg. RSI 
 +    LEA RDI, DestinIndexString  ; load address of variable 'DestinIndexString' into base reg. RDI 
 +    MOV AL, 0FFH     ; load the ending character 'FF' into reg. AL 
 +    XOR RCX, RCX                ; zero index register RCX, it is volatile 
 +Copy_Loop:  
 +    CMP BYTE PTR [RSI+RCX], AL  ; is it the end of a string (special character FF)?  
 +    JE String_End     ; found end character (guard)  
 +    MOV AH, [RSI+RCX]     ; take one character from source string 
 +    MOV [RDI+RCX], AH           ; put it into  destination string 
 +    ADD RCX, 1         ; increment index register 
 +    JMP Copy_Loop     ; jump to beginning of a loop  
 +String_End:  
 +    POP RDI
     POP RSI     POP RSI
-    RET                      ; return form procedure +    RET             ; return form procedure 
-FindChar_1 ENDP              ; end of FindChar_1 +CopyString_base_index ENDP ; end of CopyString_base_index
  
-;**************************************************************************** 
-;   Procedure to measure the time of other function execution 
-;   No input parameters, result is the time (number of processor ticks) 
 ;****************************************************************************  ;**************************************************************************** 
-ReadTime_1 PROC +;   This function uses base addressing mode with displacement 
-    RDTSC                    ; read of time stamp counter +;****************************************************************************  
-    MOV RCX,RAX+CopyString_base_disp PROC 
  
-    CALL FindChar_1          ; call to the tested function+; Calcucate the displacement of destination string from source 
 +    Address_difference EQU DestinDisplString - SourceDataString
  
-    RDTSC +    PUSH RSI                    ; RSI, RDI are non-volatile registers 
-    SUB RAX,RCX+    LEA RSI, SourceDataString   ; load address of variable 'SourceDataString' into base reg. RSI 
 +    MOV AL, 0FFH     ; load the ending character 'FF' into reg. AL 
 +Copy_Loop:  
 +    CMP BYTE PTR [RSI], AL      ; is it the end of a string (special character FF)?  
 +    JE String_End     ; found end character (guard)  
 +    MOV AH, [RSI]         ; take one character from source string 
 +    MOV [RSI+Address_difference], AH   ; put it into destination string 
 +    ADD RSI, 1         ; increment index register 
 +    JMP Copy_Loop     ; jump to beginning of a loop  
 +String_End:  
 +    POP RSI 
 +    RET             ; return form procedure 
 +CopyString_base_disp ENDP     ; end of CopyString_base_disp
  
-    RET                      ; return form procedure +;**************************************************************************** 
-ReadTime_1 ENDP +
  
 END END
-;****************************************************************************  
-    End of the file 
-;****************************************************************************  
 </code> </code>
  
 +*def file*
 +<code>
 +LIBRARY JaAsm
 +EXPORTS CopyString_base
 +EXPORTS CopyString_base_index
 +EXPORTS CopyString_base_disp
 +</code>
 ===== Tasks to be done during laboratory ===== ===== Tasks to be done during laboratory =====
-  - Compile the example code and observe its behaviour. Set the breakpoint at the beginning of the code and see how the contents of the registers change with every loop pass.  +1. Compile the example code and observe its behaviour. Set the breakpoint at the beginning of the code and see how the contents of the registers change with every loop pass.\\ 
-  - Make the function more universal: define the string in a C++ file and pass its address as the parameter to the function. Pass the character as the second parameter. +2. Observe the content of the memory at the beginning address of the source string. Look if other strings are filled properly.\\ 
-  - Rewrite the search algorithm with vector instructions (SSE, or AVX). Suggest what to do if the string length is not a multiple of register size. +3. Write the version of the assembler function which copies the source to a destination string using chosen string instruction with repetition (use REP prefix). 
-  - Compare execution time for scalar (normal) instructions and vector instruction for the same string.+===== For the report ===== 
 +1. Put in the report a screenshot of the window with the results displayed (memory dump with copied texts).\\ 
 +2. Explain differences in addressing modes used in the functions. Explain what is the result of the line: 
 +<code> 
 +Address_difference EQU DestinDisplString - SourceDataString 
 +</code> 
 +3. Include the code of your new function written in assembler WITH COMMENTS. Also, add a screenshot of the window with the results displayed (copied texts). 
 + 
en/edu/zmitac/s1/apl/lab/lab3.1732715359.txt.gz · Last modified: by ktokarz