isu-examples/rw32-2022.inc
2023-04-26 10:13:12 +02:00

1376 lines
26 KiB
PHP

; Verze: 2022.02
; Autor: Filip Orsag (orsag@fit.vutbr.cz)
;
; Podpurna knihovna funkci "rw32-20XX.inc" pro predmet ISU.
; Pro svou cinnost vyuziva standardni knihovny jazyka C.
; Lze ji pouzit v OS Windows nebo Linux.
;
; Knihovnu vkladejte na zacatek vaseho programu:
;
; %include "rw32-20XX.inc"
;
; Preklad Windows:
; nasm -f win32 -g -o helloworld.obj helloworld.asm
; golink helloworld.obj /fo helloworld.exe /console /debug coff /entry:_main msvcrt.dll kernel32.dll
;
; Preklad Linux:
; nasm -f elf32 -g -o helloworld.o helloworld.asm
; gcc -m32 -o helloworld helloworld.o
;
;
; Dostupne funkce jsou nasledujici:
;
; Cteni z klavesnice:
; (verze '_Silent' nevypisuji nic na obrazovku a v pripade chybne zadaneho cisla tuto skutecnost ignoruji)
;
; ReadChar/ReadChar_Silent
; Vstup: nic.
; Vystup: AL = hodnota znaku.
; Chovani: ceka na zadani znaku a na stisk klavesy ENTER (lze zadat i vice znaku, ale ty budou ignorovany, platny je pouze prvni znak).
; ReadString/ReadString_Silent
; Vstup: EBX = maximalni pocet znaku, ktere mohou byt nacteny.
; EDI = adresa, kam se retezec nacte (musi byt rezervovano alespon EBX+1 bytu).
; Vystup: EAX = pocet prectenych znaku
; retezec znaku ulozeny na adrese EDI.
; Chovani: nacita znaky z klavesnice, dokud neni stisknuta klavesa ENTER. Na adresu v EDI ulozi maximalne EBX znaku
; nebo mene (vsechny dalsi znaky budou ignorovany), skutecny pocet znaku vraci v registru EAX.
; ReadInt8/ReadInt8_Silent
; Vstup: nic.
; Vystup: AL = cislo z intervalu <-128, 127>.
; Chovani: cte cislo z klvesnice, umozni zadat jakykoliv znak, ale pouze znak '-','+' a cislice budou akceptovany,
; pokud neni zadana zadny znak a je stisknut ENTER, pak je vracena hodnota 0, pri prekroceni kterekoliv povolene
; meze je vraceno bud maximum nebo minimum daneho rozsahu.
; ReadInt16/ReadInt16_Silent
; Vstup: nic.
; Vystup: AX = cislo z intervalu <-32768, 32767>.
; Chovani: viz ReadInt8.
; ReadInt32/ReadInt32_Silent
; Vstup: nic.
; Vystup: EAX = cislo z intervalu <-2^31, 2^31 - 1>.
; Chovani: viz ReadInt8.
; ReadUInt8/ReadUInt8_Silent
; Vstup: nic.
; Vystup: AL = cislo z intervalu <0, 255>.
; Chovani: viz ReadInt8 s tim rozdilem, ze pri zadani znaku '-' bude cislo v doplnkovem kodu, ale interpretovano jako cislo bez znamenka.
; ReadUInt16/ReadUInt16_Silent
; Vstup: nic.
; Vystup: AX = cislo z intervalu <0, 65535>.
; Chovani: viz ReadUInt8.
; ReadUInt32/ReadUInt32_Silent
; Vstup: nic.
; Vystup: EAX = cislo z intervalu <0, 2^32 - 1>.
; Chovani: viz ReadUInt8.
; ReadFloat/ReadFloat_Silent
; Vstup: nic.
; Vystup: EAX = 32bitove realne cislo v plovouci radove carce (v jazyce C typ float).
; Chovani: viz ReadInt8, navic je dovoleno zadat znak '.' (desetinna carka) a exponent (e+N nebo e-N).
; ReadDouble/ReadDouble_Silent
; Vstup: nic.
; Vystup: ST0 = 64bitove realne cislo v plovouci radove carce (v jazyce C typ double).
; Chovani: viz ReadFloat.
; Vypis na obrazovku:
; WriteChar
; Vstup: znak v AL.
; Vystup: vypise znak na obrazovku.
; WriteNewLine
; Vstup: nic.
; Vystup: vypise konec radku ("\n").
; WriteString
; Vstup: ESI = ukazatel na retezec zakonceny hodnotou 0, ktery bude vypsan.
; Vystup: vypise retezec na obrazovku.
; WriteBin8
; Vstup: AL = cislo.
; Vystup: vypise cislo z AL na obrazovku v binarni podobe.
; WriteBin16
; Vstup: AX = cislo
; Vystup: vypise cislo z AX na obrazovku v binarni podobe.
; WriteBin32
; Vstup: EAX = cislo.
; Vystup: vypise cislo z EAX na obrazovku v binarni podobe.
; WriteHex8
; Vstup: AL = cislo.
; Vystup: vypise cislo z AL na obrazovku v hexadecimalni podobe "0xXX".
; WriteHex16
; Vstup: AX = cislo
; Vystup: vypise cislo z AX na obrazovku v hexadecimalni podobe "0xXXXX".
; WriteHex32
; Vstup: EAX = cislo.
; Vystup: vypise cislo z EAX na obrazovku v hexadecimalni podobe "0xXXXXXXXX".
; WriteInt8
; Vstup: AL = cislo.
; Vystup: vypise cislo z AL na obrazovku v dekadicke forme se znamenkem.
; WriteInt16
; Vstup: AX = cislo.
; Vystup: vypise cislo z AX na obrazovku v dekadicke forme se znamenkem.
; WriteInt32
; Vstup: EAX = cislo.
; Vystup: vypise cislo z EAX na obrazovku v dekadicke forme se znamenkem.
; WriteUInt8
; Vstup: AL = cislo.
; Vystup: vypise cislo z AL na obrazovku v dekadicke forme bez znamenka.
; WriteUInt16
; Vstup: AX = cislo.
; Vystup: vypise cislo z AX na obrazovku v dekadicke forme bez znamenka.
; WriteUInt32
; Vstup: EAX = cislo.
; Vystup: vypise cislo z EAX na obrazovku v dekadicke forme bez znamenka.
; WriteFlags
; Vstup: nic (aktualni stav priznakoveho registru).
; Vystup: vypise obsah registru priznaku EFLAGS na obrazovku.
; WriteFloat
; Vstup: EAX = cislo (realne cislo s jednoduchou presnosti - float).
; Vystup: vypise cislo z EAX na obrazovku ve forme realneho cisla.
; WriteDouble
; Vstup: ST0 = cislo (realne cislo v koprocesoru, vypisuje se cislo s dvojitou presnosti - double).
; Vystup: vypise cislo z ST0 na obrazovku ve forme realneho cisla.
;
; WriteAllGPRegisters32
; Vstup: nic (aktualni stav jednotlivych registru)
; Vystup: vypise obsah registru EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP
;
; WriteTestGPRegisters32
; Vstup: nic (aktualni stav jednotlivych registru)
; Vystup: vypise obsah registru EBX, ECX, EDX, ESI, EDI, EBP
;
; WriteArrayInt8
; Vstup: ESI = ukazatel na pole 8bitovych cisel,
; ECX = pocet prvku pole
; Vystup: vypise pole 8bitovych cisel se znamenkem
;
; WriteArrayInt16
; Vstup: ESI = ukazatel na pole 16bitovych cisel,
; ECX = pocet prvku pole
; Vystup: vypise pole 16bitovych cisel se znamenkem
;
; WriteArrayInt32
; Vstup: ESI = ukazatel na pole 32bitovych cisel,
; ECX = pocet prvku pole
; Vystup: vypise pole 32bitovych cisel se znamenkem
;
; WriteArrayUInt8
; Vstup: ESI = ukazatel na pole 8bitovych cisel,
; ECX = pocet prvku pole
; Vystup: vypise pole 8bitovych cisel bez znamenka
;
; WriteArrayUInt16
; Vstup: ESI = ukazatel na pole 16bitovych cisel,
; ECX = pocet prvku pole
; Vystup: vypise pole 16bitovych cisel bez znamenka
;
; WriteArrayUInt32
; Vstup: ESI = ukazatel na pole 32bitovych cisel,
; ECX = pocet prvku pole
; Vystup: vypise pole 32bitovych cisel bez znamenka
;
bits 32
; Funkce standardni knihovny jazyka C (C Run-Time libraray)
%ifidn __OUTPUT_FORMAT__, win32
%ifndef SASM
%macro CEXTERN 1.nolist
extern %1
%endmacro
; Nektere dalsi funkce Win32 API
CEXTERN ExitProcess
section .text
global start
start:
call _main
push dword 0
call ExitProcess
%else
%macro CEXTERN 1.nolist
%ifndef CEXTERN%1
extern _%1
%xdefine CEXTERN_%1
%xdefine %1 _%1
%endif
%endmacro
%endif
CEXTERN __iob_func
%macro PUSH_STDIN 0
cmp dword [rw_stdin],-1
jnz %%stdinOK
push eax
push 0
call __iob_func
add esp,4
mov [rw_stdin],eax
pop eax
%%stdinOK:
push dword [rw_stdin]
%endmacro
; nase vstupni funkce se bude jmenovat _main
%define CMAIN _main
%elifidn __OUTPUT_FORMAT__, elf32
%macro CEXTERN 1.nolist
extern %1
%endmacro
; nase vstupni funkce se bude jmenovat main
%define CMAIN main
extern stdin
%macro PUSH_STDIN 0
push dword [stdin]
%endmacro
%endif
global CMAIN
CEXTERN printf
CEXTERN scanf
CEXTERN sscanf
CEXTERN fgets
CEXTERN getchar
CEXTERN strlen
CEXTERN fflush
%macro STRING 2+.nolist
%1: DB %2
endof.%1: DB 0
lenof.%1 EQU endof.%1 - %1
sizeof.%1 EQU endof.%1 - %1
%endmacro
%macro INVOKE 1.nolist
call %1
%endmacro
%macro CALL_CDECL 1-*.nolist
%if %0 > 1
%rep %0-1
%rotate -1
push dword %1
%endrep
%rotate -1
%endif
call %1
add esp,(%0 - 1)*4
%endmacro
%macro CALL_PASCAL 1-*.nolist
%if %0 > 1
%rep %0-1
%rotate 1
push dword %1
%endrep
%rotate 1
%endif
call %1
%endmacro
%macro CALL_STD 1-*.nolist
%if %0 > 1
%rep %0-1
%rotate -1
push dword %1
%endrep
%rotate -1
%endif
call %1
%endmacro
%define PAR_CDECL(i,N) EBP + 4 + i*4
%define PAR_STD(i,N) EBP + 4 + i*4
%define PAR_PASCAL(i,N) EBP + 4 + N*4 - (i - 1)*4
%define RET_CDECL(N) RET
%define RET_STD(N) RET N*4
%define RET_PASCAL(N) RET N*4
%macro PRINTF 0-*.nolist
%assign incStack 0
%if %0 > 0
%rep %0
%rotate -1
%ifstr %1
section .data
%%str: db %1, 0
section .text
push %%str
%else
push dword %1
%endif
%assign incStack incStack+4
%endrep
%rotate -1
%endif
call printf
%if incStack > 0
add esp,incStack
%endif
push 0
call fflush
add esp,4
%endmacro
%imacro MOVSTR 2+
section .data
%%str: db %2, 0
section .text
mov %1,%%str
%endmacro
%imacro dbg_reg 2-*
%ifdef DEBUG
pushad
push dword %1
push msg_dump_begin_format
call printf
add esp,8
popad
%rotate 1
%assign i 0
%rep %0-1
%assign i i+1
%defstr %%dbgnamestr %1
section .data
%%dbgname %+ i: db %%dbgnamestr,0
section .text
pushad
mov [tmp],dword 0
mov [tmp], %1
push dword [tmp]
push %%dbgname %+ i
push msg_dump_format
call printf
add esp,12
popad
%undef %%dbgnamestr
%rotate 1
%endrep
pushad
push msg_dump_end_format
call printf
add esp,4
popad
%endif
%endmacro
%define KB_ENTER 0x0D
%define KB_NEWLINE 0x0A
%define KB_BACKSPACE 0x08
%define EOL KB_NEWLINE
; Konstanty
%define EOF -1
%define MAX_UBYTE 0xFF
%define MAX_UWORD 0xFFFF
%define MAX_UDWORD 0xFFFFFFFF
%define MAX_SBYTE 0x0000007F
%define MAX_SWORD 0x00007FFF
%define MAX_SDWORD 0x7FFFFFFF
%define MIN_SBYTE 0xFFFFFF80
%define MIN_SWORD 0xFFFF8000
%define MIN_SDWORD 0x80000000
%define MAX_STRING_LENGTH 1024
section .data align=4
STRING msg_EOL, `\n`
STRING msg_EnterChar, 'Zadejte znak: '
STRING msg_EnterUInt, 'Zadejte cele cislo bez znamenka z intervalu <%u,%u>: '
STRING msg_EnterSInt, 'Zadejte cele cislo se znamenkem z intervalu <%d,%d>: '
STRING msg_EnterFloat, 'Zadejte realne cislo (napr. 1.5): '
STRING msg_EnterText, 'Zadejte text (akceptovano bude maximalne %d znaku): '
STRING msg_NumberTooBig, `Cislo je prilis velke, vracim maximalni moznou hodnotu.\n`
STRING msg_NumberTooLow, `Cislo je prilis male, vracim minimalni moznou hodnotu.\n`
STRING msg_WrongNumber, 'Zadana hodnota neni rozpoznatelne cislo. Zadejte nove CISLO: '
STRING msg_NoRegChanges, 'REG CHECK OK'
STRING msg_regChanges, 'REG CHECK FAILED'
STRING s_EAX, 'EAX'
STRING s_EBX, 'EBX'
STRING s_ECX, 'ECX'
STRING s_EDX, 'EDX'
STRING s_ESI, 'ESI'
STRING s_EDI, 'EDI'
STRING s_EBP, 'EBP'
STRING s_ESP, 'ESP'
msg_dump_begin_format db "--- DEBUG BEGIN --- (at line: %d)",EOL,0
msg_dump_end_format db "--- DEBUG END ---",EOL,0
msg_dump_format db "%s = %d",EOL,0
msg_Flags db 'Flags: xxxx|OF|DF|IF|TF|SF|ZF|xx|AF|xx|PF|xx|CF|',EOL,' xxxx| '
msg_FlagValues db 'x| x| x| x| x| x| x| x| x| x| x| x|',EOL
endof_msg_Flags db 0
lenof_msg_Flags EQU endof_msg_Flags - msg_Flags
rw_stdin dd -1
number_in dq 0.0
tmp dd 0
tmpEAX dd 0
reg_dump_b dd 0,0,0,0,0,0,0,0
reg_dump dd 0
ioBuffer times MAX_STRING_LENGTH db '!'
db 0
section .text
;----------------
; Funkce ReadString/ReadString_Silent
;
%macro READ_STRING 1-2
%1:
enter 0,0
pushfd
push esi
push edi
push ebx
push ecx
push edx
%if %0 > 1
PRINTF %2, ebx
%endif
mov [edi], byte 0
test ebx,ebx
jz .return
PUSH_STDIN
push dword MAX_STRING_LENGTH
push ioBuffer
INVOKE fgets
add esp,12
mov [ioBuffer + ebx], byte 0
push ioBuffer
INVOKE strlen
add esp,4
mov ecx,eax
cmp [ioBuffer + ecx - 1], byte 10
je .is_new_line
inc ecx
.is_new_line:
mov [ioBuffer + ecx - 1], byte 0
mov esi,ioBuffer
rep movsb
.return:
pop edx
pop ecx
pop ebx
pop edi
pop esi
popfd
leave
ret
%endmacro
;----------------
; Funkce ReadString_Silent
;
READ_STRING ReadString_Silent
;----------------
; Funkce ReadString
;
READ_STRING ReadString, msg_EnterText
;----------------
; Funkce ReadChar_Silent
;
ReadChar_Silent:
enter 0,0
pushfd
push esi
push ecx
push edx
jmp ReadChar.skipMsg
;----------------
; Funkce ReadChar
;
ReadChar:
enter 0,0
pushfd
push esi
push ecx
push edx
mov esi,msg_EnterChar
call WriteString
.skipMsg:
PUSH_STDIN
push dword MAX_STRING_LENGTH
push ioBuffer
INVOKE fgets
add esp,12
movzx eax,byte [ioBuffer]
.return:
pop edx
pop ecx
pop esi
popfd
leave
ret
;----------------
; Funkce ReadNumber/ReadNumber_Silent
; Cte cislo ze standardniho vstupu dle formatovaciho retezce odpovidajiciho formatu scanf.
; Ukazatel na formatovaci retezec je ulozen v registru EBX.
;
%macro READ_NUMBER 1-2
%1:
enter 0,0
push ebx
push ecx
push edx
.again:
mov [number_in], dword 0
mov [number_in + 4], dword 0
PUSH_STDIN
push MAX_STRING_LENGTH
push ioBuffer
INVOKE fgets
add esp,12
push number_in
push ebx
push ioBuffer
INVOKE sscanf
add esp,12
cmp eax,0
jne .ok
%if %0 > 1
PRINTF "%s", %2
jmp .again
%endif
.ok:
mov eax,[number_in]
pop edx
pop ecx
pop ebx
leave
ret
%endmacro
;----------------
; Funkce ReadNumber_Silent
;
READ_NUMBER ReadNumber_Silent
;----------------
; Funkce ReadNumber
;
READ_NUMBER ReadNumber, msg_WrongNumber
%macro CREATE_READNUMBER_PROLOGUE 5-6
%1:
enter 0,0
push esi
push edi
push ebx
mov edi,%2
mov ebx,%3
%if %0 > 5
push ecx
push edx
PRINTF %6, edi, ebx
pop edx
pop ecx
push ebx
MOVSTR ebx,%5
call ReadNumber
pop ebx
jmp %4
%else
push ebx
MOVSTR ebx,%5
call ReadNumber_Silent
pop ebx
jmp %4
%endif
%endmacro
;----------------
; Funkce ReadIntX (8,16,32) {ReadInt8,ReadInt16,ReadInt32}
; Precte 8-, 16-, 32-bitovou celociselnou hodnotu se znamenkem z klavesnice
; Chovani funkci je dano chovanim funkce SSCANF. Veskere namitky se netykaji autora.
;
CREATE_READNUMBER_PROLOGUE ReadInt8,MIN_SBYTE,MAX_SBYTE,ReadInt,"%d",msg_EnterSInt
CREATE_READNUMBER_PROLOGUE ReadInt16,MIN_SWORD,MAX_SWORD,ReadInt,"%d",msg_EnterSInt
CREATE_READNUMBER_PROLOGUE ReadInt32,MIN_SDWORD,MAX_SDWORD,ReadInt,"%d",msg_EnterSInt
CREATE_READNUMBER_PROLOGUE ReadInt8_Silent,MIN_SBYTE,MAX_SBYTE,ReadInt,"%d"
CREATE_READNUMBER_PROLOGUE ReadInt16_Silent,MIN_SWORD,MAX_SWORD,ReadInt,"%d"
CREATE_READNUMBER_PROLOGUE ReadInt32_Silent,MIN_SDWORD,MAX_SDWORD,ReadInt,"%d"
ReadInt:
cmp eax,ebx
jng .test_min
; mov esi,msg_NumberTooBig
; call WriteString
mov eax,ebx
jmp .return
.test_min:
cmp eax,edi
jnl .return
; mov esi,msg_NumberTooLow
; call WriteString
mov eax,edi
.return:
pop ebx
pop edi
pop esi
leave
ret
;----------------
; Funkce ReadUIntX (8,16,32) {ReadUInt8,ReadUInt16,ReadUInt32}
; Precte 8-, 16-, 32-bitovou celociselnou hodnotu bez znamenka z klavesnice
; Chovani funkci je dano chovanim funkce SSCANF. Veskere namitky se netykaji autora.
;
CREATE_READNUMBER_PROLOGUE ReadUInt8,0,MAX_UBYTE,ReadUInt,"%u",msg_EnterUInt
CREATE_READNUMBER_PROLOGUE ReadUInt16,0,MAX_UWORD,ReadUInt,"%u",msg_EnterUInt
CREATE_READNUMBER_PROLOGUE ReadUInt32,0,MAX_UDWORD,ReadUInt,"%u",msg_EnterUInt
CREATE_READNUMBER_PROLOGUE ReadUInt8_Silent,0,MAX_UBYTE,ReadUInt,"%u"
CREATE_READNUMBER_PROLOGUE ReadUInt16_Silent,0,MAX_UWORD,ReadUInt,"%u"
CREATE_READNUMBER_PROLOGUE ReadUInt32_Silent,0,MAX_UDWORD,ReadUInt,"%u"
ReadUInt:
cmp eax,ebx
jna .return
; mov esi,msg_NumberTooBig
; call WriteString
mov eax,ebx
.return:
pop ebx
pop edi
pop esi
leave
ret
;----------------
; Funkce ReadFloat
; Precte 32bitove realne cislo z klavesnice
; Chovani funkci je dano chovanim funkce SSCANF. Veskere namitky se netykaji autora.
;
ReadFloat:
enter 0,0
pushfd
push esi
push ebx
mov esi,msg_EnterFloat
call WriteString
MOVSTR ebx,"%lf"
call ReadNumber
fld qword [number_in]
sub esp,4
fstp dword [esp]
pop eax
.return:
pop ebx
pop esi
popfd
leave
ret
ReadFloat_Silent:
enter 0,0
pushfd
push ebx
MOVSTR ebx,"%lf"
call ReadNumber_Silent
fld qword [number_in]
sub esp,4
fstp dword [esp]
pop eax
.return:
pop ebx
popfd
leave
ret
;----------------
; Funkce ReadDouble
; Precte 64bitove realne cislo z klavesnice
; Chovani funkci je dano chovanim funkce SSCANF. Veskere namitky se netykaji autora.
;
ReadDouble:
enter 0,0
pushfd
push esi
push ebx
push eax
mov esi,msg_EnterFloat
call WriteString
MOVSTR ebx,"%lf"
call ReadNumber
fld qword [number_in]
.return:
pop eax
pop ebx
pop esi
popfd
leave
ret
ReadDouble_Silent:
enter 0,0
pushfd
push ebx
push eax
MOVSTR ebx,"%lf"
call ReadNumber_Silent
fld qword [number_in]
.return:
pop eax
pop ebx
popfd
leave
ret
;----------------
; WriteChar
; Vypise znak ulozeny v registru AL
;
WriteChar:
enter 0,0
push eax
push ecx
push edx
PRINTF "%c",eax
pop edx
pop ecx
pop eax
leave
ret
;----------------
; WriteNewLine
; Vypise "End Of Line", tedy ASCII hodnoty CR, LF ve Windows (13, 10) a LF v Linuxu (10)
;
WriteNewLine:
enter 0,0
pushfd
push eax
push ecx
push edx
PRINTF "%s",msg_EOL
pop edx
pop ecx
pop eax
popfd
leave
ret
;----------------
; Funkce WriteBinX (8, 16, 32) {WriteBin8, WriteBin16, WriteBin32}
; Vypise 8,16,32 bitu z registru AL, AX, EAX
;
WriteBin8:
enter 0,0
pushfd
pushad
mov ecx,8
rcl eax,24
jmp WriteBin
WriteBin16:
enter 0,0
pushfd
pushad
mov ecx,16
rcl eax,16
jmp WriteBin
WriteBin32:
enter 0,0
pushfd
pushad
mov ecx,32
WriteBin:
cld
mov edi,ioBuffer
mov ebx,eax
.next_bit:
rcl ebx,1
setc al
add al,'0'
stosb
loop .next_bit
mov [edi], byte 0
mov esi,ioBuffer
call WriteString
popad
popfd
leave
ret
;----------------
; WriteString
; Vypise retezce ukonceneho 0 (ASCIIZ), jehoz adresa je ulozena v registru ESI
;
WriteString:
enter 0,0
;pushfd
push eax
push ecx
push edx
PRINTF "%s", esi
sub eax,eax
stc
pop edx
pop ecx
pop eax
;popfd
leave
ret
;----------------
; WriteFlags
; Vypise stav registru priznaku
;
WriteFlags:
enter 0,0
pushfd
pushad
pushfd
pop ebx
shl ebx,20
mov ecx,12
mov edi,msg_FlagValues
.cycle:
rcl ebx,1
setc al
add al,'0'
mov [edi],al
add edi,3
loop .cycle
mov esi,msg_Flags
call WriteString
popad
popfd
leave
ret
;----------------
; Funkce WriteIntX (8,16,32) {WriteInt8,WriteInt16,WriteInt32}
; Vypise 8-, 16-, 32-bitovou celociselnou hodnotu se znamenkem z registru AL, AX, EAX
;
;----------------
; Funkce WriteUIntX (8,16,32) {WriteUInt8,WriteUInt16,WriteUInt32}
; Vypise 8-, 16-, 32-bitovou celociselnou hodnotu bez znamenka z registru AL, AX, EAX
;
; Chovani funkci je dano chovanim funkce PRINTF a prislusnym formatovacim retezcem.
;
WriteInt8:
enter 0,0
pushfd
push eax
movsx eax,al
jmp WriteInt
WriteUInt8:
enter 0,0
pushfd
push eax
movzx eax,al
jmp WriteUInt
WriteInt16:
enter 0,0
pushfd
push eax
movsx eax,ax
jmp WriteInt
WriteUInt16:
enter 0,0
pushfd
push eax
movzx eax,ax
jmp WriteUInt
WriteInt32:
enter 0,0
pushfd
push eax
WriteInt:
push ecx
push edx
PRINTF "%d", eax
pop edx
pop ecx
pop eax
popfd
leave
ret
WriteUInt32:
enter 0,0
pushfd
push eax
WriteUInt:
push ecx
push edx
PRINTF "%u", eax
pop edx
pop ecx
pop eax
popfd
leave
ret
;----------------
; Funkce WriteHexX (8,16,32) {WriteHex8,WriteHex16,WriteHex32}
; Vypise hexadecimalne 8-, 16-, 32-bitovou celociselnou hodnotu bez znamenka z registru AL, AX, EAX
;
; Chovani funkci je dano chovanim funkce PRINTF a prislusnym formatovacim retezcem.
;
WriteHex8:
enter 0,0
pushfd
push eax
push esi
movzx eax,al
MOVSTR esi,"0x%02X"
jmp WriteHex
WriteHex16:
enter 0,0
pushfd
push eax
push esi
movzx eax,ax
MOVSTR esi,"0x%04X"
jmp WriteHex
WriteHex32:
enter 0,0
pushfd
push eax
push esi
MOVSTR esi,"0x%08X"
WriteHex:
push ecx
push edx
PRINTF esi, eax
pop edx
pop ecx
pop esi
pop eax
popfd
leave
ret
;----------------
; Funkce WriteFloat
; Vypise 32-bitove realne cislo z registru EAX
;
WriteFloat:
enter 0,0
pushfd
push eax
push ecx
push edx
push eax
fld dword [esp]
sub esp, 4
fstp qword [esp]
PRINTF "%f" ; printf vyzaduje vzdy double!
add esp,8
pop edx
pop ecx
pop eax
popfd
leave
ret
;----------------
; Funkce WriteFloat
; Vypise 32-bitove realne cislo z registru EAX
;
WriteFloatP1:
enter 0,0
pushfd
push eax
push ecx
push edx
push eax
fld dword [esp]
sub esp, 4
fstp qword [esp]
PRINTF "%.1f" ; printf vyzaduje vzdy double!
add esp,8
pop edx
pop ecx
pop eax
popfd
leave
ret
;----------------
; Funkce WriteDouble
; Vypise 64-bitove realne cislo z registru koprocesoru ST0
;
WriteDouble:
enter 0,0
pushfd
push eax
push ecx
push edx
sub esp,8
fst qword [esp]
PRINTF "%lf"
add esp,8
pop edx
pop ecx
pop eax
popfd
leave
ret
;----------------
; Funkce WriteAllGPRegisters32
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
WriteAllGPRegisters32:
pushfd
pushad
PRINTF `EAX=0x%08X,EBX=0x%08X,ECX=0x%08X,EDX=0x%08X,ESI=0x%08X,EDI=0x%08X,EBP=0x%08X,ESP=0x%08X\n`, eax, ebx, ecx, edx, esi, edi, ebp, esp
popad
popfd
ret
;----------------
; Funkce WriteTestGPRegisters32
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
WriteTestGPRegisters32:
pushfd
pushad
PRINTF `EBX=0x%08X,ECX=0x%08X,EDX=0x%08X,ESI=0x%08X,EDI=0x%08X,EBP=0x%08X\n`, ebx, ecx, edx, esi, edi, ebp
popad
popfd
ret
RegDump:
mov [tmp],esp
mov esp,reg_dump+4
pushad
mov esp,[tmp]
mov [reg_dump - 16],esp
ret
;----------------
; Funkce WriteDiffTestGPRegisters32
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
WriteDiffTestGPRegisters32:
;EAX ~ ESP + 28 (-0)
;ECX ~ ESP + 24 (-4)
;EDX ~ ESP + 20 (-8)
;EBX ~ ESP + 16 (-12)
;old ESP ~ ESP + 12 (-16)
;EBP ~ ESP + 8 (-20)
;ESI ~ ESP + 4 (-24)
;EDI ~ ESP + 0 (-28)
mov [tmp],esp
pushfd
pushad
mov ebp,esp
; cmp eax,[reg_dump - 0]
; jz .ebx
; push s_EAX
;.ebx:
cmp ebx,[reg_dump - 12]
jz .ecx
push s_EBX
.ecx:
cmp ecx,[reg_dump - 4]
jz .edx
push s_ECX
.edx:
cmp edx,[reg_dump - 8]
jz .esi
push s_EDX
.esi:
cmp esi,[reg_dump - 24]
jz .edi
push s_ESI
.edi:
cmp edi,[reg_dump - 28]
jz .ebp
push s_EDI
.ebp:
mov eax,[ebp + 8]
cmp eax,[reg_dump - 20]
jz .esp
push s_EBP
.esp:
mov eax,[tmp]
cmp eax,[reg_dump - 16]
jz .write
push s_ESP
.write:
mov ecx,ebp
sub ecx,esp
shr ecx,2
cmp ecx,0
jz .no_changes
mov esi,msg_regChanges
call WriteString
.write_next:
pop esi
; call WriteString
cmp ecx,1
jz .skip_comma
mov al,','
; call WriteChar
.skip_comma:
loop .write_next
jmp .exit
.no_changes:
mov esi,msg_NoRegChanges
call WriteString
.exit:
;call WriteNewLine
popad
popfd
ret
;----------------
; Funkce WriteDiffTestGPRegisters32
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
HaveGPRegisters32Changed:
;EAX ~ ESP + 28 (-0)
;ECX ~ ESP + 24 (-4)
;EDX ~ ESP + 20 (-8)
;EBX ~ ESP + 16 (-12)
;old ESP ~ ESP + 12 (-16)
;EBP ~ ESP + 8 (-20)
;ESI ~ ESP + 4 (-24)
;EDI ~ ESP + 0 (-28)
mov [tmp],esp
pushfd
pushad
mov ebp,esp
cmp ebx,[reg_dump - 12]
jnz .changed
cmp ecx,[reg_dump - 4]
jnz .changed
cmp edx,[reg_dump - 8]
jnz .changed
cmp esi,[reg_dump - 24]
jnz .changed
cmp edi,[reg_dump - 28]
jnz .changed
mov eax,[ebp + 8]
cmp eax,[reg_dump - 20]
jnz .changed
mov eax,[tmp]
cmp eax,[reg_dump - 16]
jnz .changed
mov [tmpEAX],dword 1
jmp .exit
.changed:
mov [tmpEAX],dword 0
.exit:
popad
popfd
mov eax,[tmpEAX]
ret
%macro CREATE_WRITE_ARRAY 2.nolist
; datovy typ (b,w,d), funkce pro vypis z RW32
WriteArray%2:
enter 0,0
pushfd
push esi
push ecx
push eax
test esi,esi
jnz %%ptr_ok
PRINTF 'NULL'
jmp %%exit
%%ptr_ok:
mov al,'['
call WriteChar
cmp ecx,0
jle %%end
%%writeElement:
lods%1
call Write%2
cmp ecx,1
jbe %%skipComma
mov al,','
call WriteChar
mov al,' '
call WriteChar
%%skipComma:
loop %%writeElement
%%end:
mov al,']'
call WriteChar
;call WriteNewLine
%%exit:
pop eax
pop ecx
pop esi
popfd
leave
ret
%endmacro
;----------------
; Funkce WriteArrayInt8
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY b, Int8
;----------------
; Funkce WriteArrayInt16
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY w, Int16
;----------------
; Funkce WriteArrayInt32
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY d, Int32
;----------------
; Funkce WriteArrayUInt8
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY b, UInt8
;----------------
; Funkce WriteArrayUInt16
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY w, UInt16
;----------------
; Funkce WriteArrayUInt32
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY d, UInt32
;----------------
; Funkce WriteArrayFloat
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY d, Float
;----------------
; Funkce WriteArrayFloatP1
; Vypise pole cisel, ukazatel na pole je v ESI, pocet cisel je v ECX
;
CREATE_WRITE_ARRAY d, FloatP1