x86 výskyt výskytu znaku
- Úvod
- Problém
- Řešení
- Vysvětlení
Úvod
Níže uvedené malé montážní cvičení je určeno pro architektury x86 (Intel a AMD 32 bit) a používá syntaxi NASM, assembler, který je k dispozici zdarma a
které lze použít na různých platformách, jako jsou Windows nebo Linux.
Všimněte si, že použité externí funkce pocházejí ze standardní knihovny C.
Problém
Představte si pole znaků (které nemusí končit číslem 0). Má svou velikost a chtěli bychom otestovat přítomnost daného charakteru
v tomto poli. Cílem bude napsat funkci, která má jako vstup pole znaků, velikosti a charakteru. Pokud je tento znak přítomen
pole vrátí nenulovou hodnotu, jinak vrátí nulu.
Zde je to, co dává tuto funkci v C:
/ funkce int is_in_array (char * array, int velikost, char c); // implementace: char karta [] = {'n', 'e', 'u', 'e'}; is_in_array (tab, sizeof (tab), 'u'); // Vrátí hodnotu jinou než 0 is_in_array (tab, sizeof (tab), 'a'); // Vrátit hodnotu 0 Jednoduše vložte svůj kód do: extern printf sekce .data array db 'dadedidadedavivoufufifamasibifisaz' yes db 'oui', 10, 0 no db 'non', 10, 0 sekce .text global main is_in_array:; tam hlavní: push ebp mov ebp, esp; Test, zda m je v poli stisknout dword 'm'; Délka pole (zde 34) stisknout dword 34; řetězec adresa v poli eax push; volání is_in_array s adresou pole, ; size, a hodnota, kterou hledáte, je test_in_array test eax, eax jnz is_there; Pokud eax! = 0 zobrazí yes push no; pak nezobrazí žádný jmp screendisplay; opustit ret
To určitě nebude stačit .....
Řešení
is_in_array:; Načte adresu pole (první parametr) v edi mov edi, [esp + 4]; načte velikost pole (druhý parametr) v ecx mov ecx, [esp + 8]; (třetí parametr) v eax mov eax, [esp + 12]; Vyhledávání znaku repne scasb; Pokud má příznak ZERO (ZF) hodnotu 1, znamená to, že znak je nalezen, v druhém případě není nalezen; hodnota ZF v eax mov eax, 0; Pokud ZF = 1 pak al = 1 (al je 8 nejméně významných bitů eax) setz al ret
Vysvětlení
ZF = 0 ecx = délka eax = znak edi = array // Smyčka, která definuje "repne scasb" Zatímco ecx! = 0 ET ZF = 0 Pokud al == [edi] Pak ZF = 1 FinSi ecx = ecx - 1 edi = edi + 1 EndWhile eax = 0 // Podmínka, která definuje "setz" Si ZF = 1 Alors eax = 1 EndIf