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

Differences

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

Link to this comparison view

Next revision
Previous revision
en:edu:zmitac:s1:apl:lab:lab4 [2024/11/27 14:52] – created ktokarzen:edu:zmitac:s1:apl:lab:lab4 [2024/12/05 12:39] (current) – [Tasks to be done during laboratory] ktokarz
Line 1: Line 1:
 ====== Programming in Assembler Laboratory ====== ====== Programming in Assembler Laboratory ======
 ===== Laboratory 4 ===== ===== Laboratory 4 =====
-DLL functions call and parameters passing.+Use of vector instructions.
 ===== The aim of the exercise ===== ===== The aim of the exercise =====
-The aim of the exercise is to learn about calling library functions written in assembler from the application level. During the laboratory we'll show 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 vector instructions called SIMD (Single Instruction Multiple Data) and passing parameters to functions as references to common memory. 
-<note>Calling assembler functions from high-level language programs is currently the most common assembler use.</note>+As in previous laboratory exercises, we'll write the dll library with functions called from the C++ program. 
 +Functions will calculate the sum, difference, multiplication, and division of four single precision floating point values.
 <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> <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 ===== +===== First 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.+In the first example, we'll write the function in assembler with an internal definition of variables to show how to define floating point vectors in the assembly program. 
 +The following code is divided into three parts. The C++ part calls the function in a dynamically linked library. The function, called Sum_of_vectors(), written in the assembler file, calculates the sum of two vectors of four single precision floating point data. They are defined as first_vector and second_vector. The resulting value is stored in the resulting_vector variable. The third file is a def file which exports the function from the assembler source to the C++ program.
  
 C++ file C++ file
Line 22: Line 24:
     std::cout << "Hello World!\n";     std::cout << "Hello World!\n";
     dllHandle = LoadLibrary(TEXT("JaAsm.dll"));     dllHandle = LoadLibrary(TEXT("JaAsm.dll"));
-    std::cout << procedura(); +    MyProc Sum_of_vectors = (MyProc)GetProcAddress(dllHandle, "Sum_of_vectors"); 
- +     
-    MyProc FindChar = (MyProc)GetProcAddress(dllHandle, "FindChar_1"); +    Sum_of_vectors();
-    MyProc ReadTime = (MyProc)GetProcAddress(dllHandle, "ReadTime_1"); +
- +
-    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>
Line 36: Line 33:
 <code> <code>
 ;**************************************************************************** ;****************************************************************************
-;   String definition+;   Vectors definition
 ;**************************************************************************** ;****************************************************************************
 .data  .data 
-DataString DB 'AGIKSZJ', 0FFH; string definition  +first_vector REAL4 2.2, 4.4, 6.6, 8.8 
 +second_vector REAL4 1.1, 1.1, 1.1, 1.1 
 +resulting_vector REAL4 0.0, 0.0, 0.0, 0.0 
  
 .code .code
 ;**************************************************************************** ;****************************************************************************
-;   Procedure to find the character in a string +;   Function to calculate the sum of two vectors 
-;   No input parameters, result is 1 if character found, 0 otherwise+;   No input parameters, no result returned
 ;**************************************************************************** ;****************************************************************************
-FindChar_1 PROC  + 
-    PUSH RSI +Sum_of_vectors PROC  
-    LEA RSI, DataString      ; load the address of variable 'DataString' into reg. ESI  +    PUSH RSI                              ; RSI is non-volatile register 
-    MOV AL, 'J'              ; load the code of character 'J' into reg. AH  +    LEA RSI, first_vector                 ; this helps to find the address in the memory for dump 
-Check_End:  +             
-    CMP BYTE PTR [RSI], 0FFH ; is it the end of a string (special character FF)?  +    MOVUPS XMM0, OWORD PTR first_vector   ; load address of variable 'SourceDataString' into reg. RSI 
-    JE Not_Find              ; found end character (guard)  +    MOVUPS XMM1, OWORD PTR second_vector  ; load address of variable 'DestinBaseString' into reg. RDI 
-    CMP AL, [RSI]            ; compare a character with chosen char of string 'DataString'  +    ADDPS  XMM0, XMM1 
-    JE Got_Equal             ; character found!  +    MOVUPS OWORD PTR resulting_vector, XMM0 
-    ADD RSI, 1               ; increment an offset +
-    JMP Check_End            ; search loop  +
-Got_Equal:  +
-    MOV DL, [RSI]            ; load found char into DL  +
-    JMP Done  +
-Not_Find:  +
-    MOV RAX,0                ; character not found +
     POP RSI     POP RSI
-    RET                      ; return from procedure  +    RET           ; return form procedure 
-Done:  +Sum_of_vectors ENDP           ; end of CopyString_base    
-    MOV RAX,1                ; character found +
-    POP RSI +
-    RET                      ; return form procedure +
-FindChar_1 ENDP              ; end of FindChar_1 +
  
-;**************************************************************************** +END
-;   Procedure to measure the time of other function execution +
-;   No input parameters, result is the time (number of processor ticks)+
 ;****************************************************************************  ;**************************************************************************** 
-ReadTime_1 PROC +    End of the file 
-    RDTSC                    ; read of time stamp counter +;****************************************************************************  
-    MOV RCX,RAX+</code>
  
-    CALL FindChar_1          ; call to the tested function+Def file.
  
-    RDTSC +<code> 
-    SUB RAX,RCX+LIBRARY JaAsm 
 +EXPORTS Sum_of_vectors 
 +</code>
  
-    RET                      ; return form procedure +===== Second example code ===== 
-ReadTime_1 ENDP +In the second example, we'll write the function in assembler which accepts arguments as three addresses (pointers) to tables of floats defined in a C++ program. The first and second vectors are source while the third argument is a placeholder for the result of calculations. 
 +The following code is divided into three parts. The C++ part defines the vectors and calls the function in a dynamically linked library passing the addresses of variables as arguments. The function, called Sum_of_vectors(), written in the assembler file, calculates the sum of two vectors and modifies the content of memory pointed by the third parameter, to return the result. The third file is a def file which exports the function from the assembler source to the C++ program.
  
-END+C++ file 
 +<code> 
 +#include <iostream> 
 +#include <windows.h> 
 + 
 +typedef float FloatTable[4]; 
 +typedef FloatTable* FloatPtr; 
 + 
 +typedef int(_stdcall* MyProc)(FloatPtr, FloatPtr, FloatPtr); 
 +HINSTANCE dllHandle = NULL; 
 + 
 +FloatTable first_vector { 2.2f, 4.4f, 6.6f, 8.8f }; 
 +FloatTable second_vector{ 1.1f, 1.1f, 1.1f, 1.1f }; 
 +FloatTable result_vector{ 0.0, 0.0, 0.0, 0.0 }; 
 + 
 + 
 +int main() 
 +{ 
 +    std::cout << "Hello World!\n"; 
 +    dllHandle = LoadLibrary(TEXT("JaAsm.dll")); 
 +     
 +    MyProc Sum_of_vectors = (MyProc)GetProcAddress(dllHandle, "Sum_of_vectors"); 
 +         
 +    Sum_of_vectors(&first_vector, &second_vector, &result_vector); 
 +    std::cout << "Result_1 " << (result_vector[0]) << std::endl; 
 +    std::cout << "Result_2 " << (result_vector[1]) << std::endl; 
 +    std::cout << "Result_3 " << (result_vector[2]) << std::endl; 
 +    std::cout << "Result_4 " << (result_vector[3]) << std::endl; 
 +} 
 +</code> 
 + 
 +Assembler file 
 +<code> 
 +.code 
 + 
 +;**************************************************************************** 
 +;   Function to calculate the sum of two vectors 
 +;   Accepts two parameters, returns result by third parameter
 ;****************************************************************************  ;**************************************************************************** 
-    End of the file+Sum_of_vectors PROC  
 +    MOVUPS XMM0, OWORD PTR [RCX]   ; load content of memory pointed by the first parameter 
 +    MOVUPS XMM1, OWORD PTR [RDX]   ; load content of memory pointed by the second parameter 
 +    ADDPS  XMM0, XMM1 
 +    MOVUPS OWORD PTR [R8], XMM0    ; store the result into memory pointed by third parameter 
 + 
 +    RET    ; return form procedure 
 +Sum_of_vectors ENDP    ; end of Sum_of_vectors  
 ;****************************************************************************  ;**************************************************************************** 
 +
 +END
 </code> </code>
 +
 +Def file is the same as in a previous example.
  
 ===== 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.  +  - Compile the examples and observe their behaviour. Set the breakpoint at the beginning of the code and see how the contents of the registers change. Observe XMM registers as calculations are performed there. 
-  - 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. +  - Write additional functions to calculate subtraction, multiplication, and division of arguments. 
-  - 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. +  - Write the program which calculates the average of the values in the table using vector (SIMD) instructions. Program assumptions: 
-  - Compare execution time for scalar (normal) instructions and vector instruction for the same string.+  * Table contains 64 float values and is defined in C++ file. 
 +  * And address of the table is passed to the function as the first argument. 
 +  * A size of the table is passed as a second argument (you can assume that the size of the table is a multiply of 4). 
 +  * Function uses SIMD instructions. 
 +  * Function returns the value as the scalar, traditionally by XMM0. 
 + 
 +=====For the report===== 
 +  - Include the code of additional functions. 
 +  - Include the code of the average program (both C++ and asm files). 
 +  - The above programs must contain comments.
en/edu/zmitac/s1/apl/lab/lab4.1732715568.txt.gz · Last modified: by ktokarz