No ACL setup yet! Denying access to everyone.
pl:edu:zmitac:n1z:ja:lab1

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
pl:edu:zmitac:n1z:ja:lab1 [2021/03/12 17:40] – [Praktyka: Zadanie do wykonania] pczekalskipl:edu:zmitac:n1z:ja:lab1 [2022/04/23 19:04] (current) – [Powtórka z teorii: Funkcje i ich wywoływanie z poziomu assemblera] pczekalski
Line 37: Line 37:
 <caption>Opcje instalacyjne część 3 - uwaga - frameworki .NET po prawej stronie trzeba zaznaczyć ręcznie!</caption> <caption>Opcje instalacyjne część 3 - uwaga - frameworki .NET po prawej stronie trzeba zaznaczyć ręcznie!</caption>
 </figure> </figure>
 +
 +=== Dodatek AsmDude do VS 2019 ===
 +Visual Studio natywnie nie posiada narzędzi wspomagających pracę dewelopera z kodem źródłowym w assemblerze. Jednak ze względu na istniejących mechanizm dodatków, można doinstalować zewnętrzne narzędzia. Nie jest to obowiązkowe, ale upraszcza pracę dewelopera, w szczególności powoduje, że kod w assemblerze zostanie pokolorowany i łatwiej będzie znaleźć ew. błędy, podczas debuggowania będą podpowiadane automatycznie wartości rejestrów, jak równnież będzie się pojawaiała (w ograniczonym zakresie) kontekstowa informacja o znaczeniu instrukcji, dyrektyw, zmiennych, etykiet, etc. Dodatek AsmDude można zainstalować za pomocą mechanizmów VS w automatyczny sposób.
 +Opis dodatku znajduje się na stronie autora((https://marketplace.visualstudio.com/items?itemName=Henk-JanLebbink.AsmDude)).
  
 ==== Wymagania ==== ==== Wymagania ====
Line 106: Line 110:
  
 == Zwrot wartości z funkcji == == Zwrot wartości z funkcji ==
-Wartość całkowita (w tym wskaźnik) zwracana jest w rejestrze RCX.\\ +Wartość całkowita (w tym wskaźnik) zwracana jest w rejestrze RAX.\\ 
 Wartości zmiennoprzecinkowa zwracana jest w rejestrze XMM0. Wartości zmiennoprzecinkowa zwracana jest w rejestrze XMM0.
  
 +== Rejestry "bezpiecznie" i "niebezpieczne" ==
 +<note warning>Niektóre z rejestrów musza pozostać niezmienione w momencie powrotu z funkcji, w stosunku do ich zawartości na początku, zaraz po wywołaniu funkcji (tzw. non-volatile). Inne rejestry można dowolnie zmieniać i nie będzie miało to wpływu na działanie systemu operacyjnego (volatile).\\ W przypadku konieczności skorzystania z tej pierwszej grupy, zawartość rejestru można odłożyć na stos lub zachować w pamięci i przywrócić przed wykonaniem instrukcji ''ret''.</note>
 +
 +Rejestry, które można bezkarnie zmieniać wewnątrz kodu assemblerowej funkcji, bez konieczności przywracania oryginalnej wartości, to ([[https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#callercallee-saved-registers|x64 calling conventions]]):
 +  * RAX, RCX, RDX, R8, R9, R10, R11, oraz XMM0-XMM5,
 +  * dodatkowo w procesorach, które są wyposażone w rejestry YMM, górne połowy rejestrów YMM0-YMM15 również można zmieniać bez konieczności przywracania ich wartości,
 +  * a ponadto w procesorach wyposażonych w funkcje AVX512VL, wszystkie rejestry ZMM, YMM oraz XMM16-XMM31.
 +Rejestry, których nie wolno zmieniać (albo raczej należy przywrócić ich oryginalne wartości przed opuszczeniem funkcji) to:
 +  * RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 oraz XMM6-XMM15.
 ==== Praktyka: Tworzenie projektu C++ i konsersja do ASM ==== ==== Praktyka: Tworzenie projektu C++ i konsersja do ASM ====
  
Line 171: Line 184:
 </figure> </figure>
  
 +=== Oznaczenie pliku ASM do kompilacji ===
 +W niektórych przypadkach zdarza się, że plik ''.asm'' nie jest automatycznie rozpoznawany jako plik źródłowy z kodem w assemblerze. W związku z tym należy jawnie poinformować o tym środowiko. W tym celu należy kliknąć nazwę pliku w drzewie projektu prawym przyciskiem i wybrać opcję ''Properites'', a następnie w sekcji ''General'' wskazać ''Item Type'' i ustawić jego wartośc na ''Microsoft Macro Assembler''. Szczegóły na rysunku {{ref>jalabstep6}}.
 +<figure jalabstep6>
 +{{:pl:edu:zmitac:n1z:ja:virtualbox_msedge_-_win10_27_03_2021_19_44_41.png?600|}}
 +<caption>Oznaczenie pliku ASM jako pliku z kodem źródłowym w assemblerze</caption>
 +</figure>
  
 +=== Instalacja dodatku kolorującego kod źródłowy w assemblerze ===
 +Na sieci jest dostępne rozszerzenie do Visual Studio o nazwie **AsmDude**, które (m.in.) automatycznie koloruje kod źródłowy w assemblerze, pomaga w pisaniu kodu (podaje nazwy etykiet, zmiennych, itp) oraz podczas debbugowania wyświetla okienka z wartościami rejestrów. Plugin ten może zostać zainstalowany poprzez managera rozszerzeń Visual Studio((https://marketplace.visualstudio.com/items?itemName=Henk-JanLebbink.AsmDude)).
 ==== Praktyka: Zadanie do wykonania ==== ==== Praktyka: Zadanie do wykonania ====
 Zaimplementuj odczyt daty (użyj funkcji ''GetSystemTime''(sysinfoapi.h)((https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime)) odczytującej strukturę ''_SYSTEMTIME''(minwinbase.h)((https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime)). Struktura składa się z 8 wartości szesnastobitowych. Zaimplementuj odczyt daty (użyj funkcji ''GetSystemTime''(sysinfoapi.h)((https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime)) odczytującej strukturę ''_SYSTEMTIME''(minwinbase.h)((https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime)). Struktura składa się z 8 wartości szesnastobitowych.
Line 192: Line 213:
 Przykładowy segment danych, który był używany w prezentacji wygląda tak:\\ Przykładowy segment danych, który był używany w prezentacji wygląda tak:\\
 <code> <code>
 +...
 +
 .data .data
 STD_INPUT_HANDLE = -10 STD_INPUT_HANDLE = -10
Line 205: Line 228:
 text_msg db "A to jest bardzo dlugi tekst do wyswietlenia w konsoli, ale bez polskich znakow!",13,10 text_msg db "A to jest bardzo dlugi tekst do wyswietlenia w konsoli, ale bez polskich znakow!",13,10
 dummy dq 0 dummy dq 0
 +
 +...
  
 </code> </code>
Line 211: Line 236:
 W tym celu trzeba użyć dyrektywy ''EXTERN'' oraz ''PROC'':\\ W tym celu trzeba użyć dyrektywy ''EXTERN'' oraz ''PROC'':\\
 <code> <code>
 +
 +...
 +
 includelib          kernel32.lib   includelib          kernel32.lib  
  
Line 219: Line 247:
 EXTERN GetStdHandle: PROC EXTERN GetStdHandle: PROC
 EXTERN GetSystemTime: PROC EXTERN GetSystemTime: PROC
 +
 +...
 +
 </code> </code>
 Zwyczajowo umieszczamy również informację o bibliotece. Zwyczajowo umieszczamy również informację o bibliotece.
Line 225: Line 256:
 Po uruchomieniu programu musimy zachować wartości pewnych rejestrów, w celu ich późniejszego przywrócenia. Na sam koniec należy również wywołać funkcję kończącą program i zwracającą tzw kod powrotu do systemu operacyjnego.\\ Po uruchomieniu programu musimy zachować wartości pewnych rejestrów, w celu ich późniejszego przywrócenia. Na sam koniec należy również wywołać funkcję kończącą program i zwracającą tzw kod powrotu do systemu operacyjnego.\\
  
-Minimalny zestaw instrukcji wygląda następująco: <code>+Minimalny zestaw instrukcji wygląda następująco:  
 +<code> 
 +...
 .code  .code 
 hello_world_asm PROC hello_world_asm PROC
Line 265: Line 298:
 Aby odczytać uchwyt do wnętrza terminala, należy skorzystać z innej funkcji: Aby odczytać uchwyt do wnętrza terminala, należy skorzystać z innej funkcji:
 <code> <code>
 +...
 mov rcx, STD_OUTPUT_HANDLE mov rcx, STD_OUTPUT_HANDLE
 call GetStdHandle call GetStdHandle
 mov stdHandle, rax mov stdHandle, rax
 +...
 </code> </code>
 Przy czym ta funkcja wymaga jednego argumentu, o który strumień danych nam chodzi. Są trzy możliwości: Przy czym ta funkcja wymaga jednego argumentu, o który strumień danych nam chodzi. Są trzy możliwości:
Line 290: Line 325:
 </code> </code>
  
-W celu wyświetlenia okienka dialogowego, należy użyć wskaźnika do okna głównego aplikacji. Jako parametry przekazywane są w kolejności: uchwyt, dwa wskaźniki, do tekstów (muszą kończyć się zerem), które mają pojawić się w nagłówku oraz treści dialogu oraz jako ostatni, maska binarna określająca, jakie mają być zastosowane przyciski i ikony w okienku dialogowym.+W celu wyświetlenia okienka dialogowego, należy użyć wskaźnika do okna głównego aplikacji. Jako parametry przekazywane są w kolejności: uchwyt, dwa wskaźniki, do tekstów (muszą kończyć się zerem, RDX to wskaźnik do treści, którą wyświetli dialog, a R8 wskaźnik do nagłówka okienka, który zotanie nadany okienku), które mają pojawić się w nagłówku oraz treści dialogu oraz jako ostatni, maska binarna określająca, jakie mają być zastosowane przyciski i ikony w okienku dialogowym((https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxa)).
 <code> <code>
 +...
 ; WINUSERAPI int WINAPI MessageBoxA( ; WINUSERAPI int WINAPI MessageBoxA(
 ;  RCX =>  _In_opt_ HWND hWnd, ;  RCX =>  _In_opt_ HWND hWnd,
Line 301: Line 337:
 mov r8, offset info_msg mov r8, offset info_msg
 mov r9, 0 ; MB_OK mov r9, 0 ; MB_OK
-and rsp, not 8 ; align stack to 16 bytes prior to API call+and rsp, not 8 
 call MessageBoxA call MessageBoxA
-</code<+... 
 +</code>
  
-<note important>Uwaga - w powyższym przypadku wykonano jawnie wyrównanie stosu do wartości podzielnej przez 16 bitów. W większości przypadków nie jest to konieczne, ponieważ organizacja danych najczęściej jest 64-bitowa. Gdyby jednak okazało się, że gdzieś został odłożony na stosie pojedynczy bajt, ulegnie to zmianie i program może rzucić wyjątkiem. W związku z tym w takim przypadku należy zadbać o wyrównanie wskaźnika stosu tak, aby był podzielny przez 16.</note>+<note important>Uwaga - w powyższym przypadku wykonano jawnie wyrównanie stosu do wartości podzielnej przez 16 (''and rsp, not 8''). W większości przypadków nie jest to konieczne, ponieważ organizacja danych najczęściej jest 64-bitowa. Gdyby jednak okazało się, że gdzieś został odłożony na stosie pojedynczy bajt lub słowo, ulegnie to zmianie i program może rzucić wyjątkiem. W związku z tym w takim przypadku należy zadbać o wyrównanie wskaźnika stosu tak, aby był podzielny przez 16.</note>
 ==== Debuggowanie i uruchamianie ==== ==== Debuggowanie i uruchamianie ====
 Uwagi praktycznie odnośnie debbugowania i podglądania pamięci: Uwagi praktycznie odnośnie debbugowania i podglądania pamięci:
pl/edu/zmitac/n1z/ja/lab1.1615567228.txt.gz · Last modified: by pczekalski