Programovanie v assembleri vo Windows x64 (x86-64): Rozdiel medzi revíziami

Smazaný obsah Přidaný obsah
Fabcde (diskusia | príspevky)
Bez shrnutí editace
Značka: editor wikitextu 2017
Fabcde (diskusia | príspevky)
Pridanie programu IntToHex (gas)
Riadok 126:
call ExitProcess
</syntaxhighlight>vynuluje obsah registra ECX a ukončí program. Jediným argumentom funkcie ExitProcess (uložený v registri ECX) je exit code programu.
 
 
 
Řádek 437 ⟶ 436:
buffer: times 20 db " " ; Najvacsie 64-bitove cislo bez znamienka ma 20 cifier (2**64 - 1 = 18446744073709551615)
enter: db 0xd,0xa
BUFFER_LEN: equ enter-buffer
lpNumberOfBytesWritten: dd 0
BUFFER_LEN: equ enter-buffer
NEWLINE_LEN: equ lpNumberOfBytesWritten-enter
 
 
Riadok 473:
mov rcx, rax ; 1. param _In_ HANDLE hFile
mov rdx, qword buffer ; 2. param _In_ LPCVOID lpBuffer
mov r8d, dword BUFFER_LEN+2 NEWLINE_LEN ; 3. param _In_ DWORD nNumberOfBytesToWrite
mov r9, lpNumberOfBytesWritten ; 4. param _Out_opt_ LPDWORD lpNumberOfBytesWritten
mov qword [rsp+20h], 0 ; 5. param _Inout_opt_ LPOVERLAPPED lpOverlapped
Riadok 484:
 
add rsp, 28h ; uvolnenie rezervovaneho miesta
</syntaxhighlight>

=== IntToHex ===
'''Výpis 3b4b''' IntToStrIntToHex.s:<syntaxhighlight lang="gas" line="1">
# IntToStrIntToHex.s
 
# kompilacia:
# as IntToStrIntToHex.s -o IntToStrIntToHex.o
# linkovanie:
# ld -e main -s IntToStrIntToHex.o -o IntToStrIntToHex.exe c:\windows\system32\kernel32.dll
# alternativna kompilacia+linkovanie:
# gcc -m64 -nostartfiles -Wl,-emain -o IntToStrIntToHex.exe IntToStrIntToHex.s c:\windows\system32\kernel32.dll
 
.global main
 
.section .data
buffer: .ascii " " # Najvacsie 64-bitove cislo bez znamienka ma 20v setnastkovej sustave 16 cifier (2**64 - 1 = 18446744073709551615ffffffffffffffff)
enter: .ascii "h\15r\12n"
lpNumberOfBytesWritten: .long 0
BUFFER_LEN = enter - buffer
NEWLINE_LEN = lpNumberOfBytesWritten - enter
lpNumberOfBytesWritten: .long 0
 
 
Řádek 507 ⟶ 511:
main:
 
IntToHex:
IntToStr:
mov $1234567890, %rax # cislo, ktore potrebujeme vypisat (delenec)
mov $1016, %rbx # zaklad ciselnej sustavy (delitel)
 
lea (buffer+BUFFER_LEN-1), %rdi # nastavi register rdi na koniec buffera (cifry budeme ziskavat smerom od najnizsieho radu k najvyssiemu)
Řádek 516 ⟶ 520:
xor %rdx, %rdx # pred delenim je nutne rdx vynulovat, inak delenie skonci chybou
div %rbx # vydeli rax / rbx, podiel vlozi do rax, zvysok do rdx
 
cmp $10, %dl # zistime, ci zvysok je mensi nez 10
jl doDesat
add $7, %dl # medzi znakom '9' a 'A' lezi v ASCII sedem znakov, ktore potrebujeme pri prevode na znak 'A'-'F' preskocit
 
doDesat:
add $'0', %dl # pripocitanim 30h prevedie cislo 0-9 na znak '0'-'9'
mov %dl, (%rdi) # ulozi ziskanu cifru do buffera
Řádek 536 ⟶ 546:
mov %rax, %rcx # 1. param _In_ HANDLE hFile
mov $buffer, %rdx # 2. param _In_ LPCVOID lpBuffer
mov $BUFFER_LEN+2NEWLINE_LEN, %r8d # 3. param _In_ DWORD nNumberOfBytesToWrite
mov $lpNumberOfBytesWritten, %r9 # 4. param _Out_opt_ LPDWORD lpNumberOfBytesWritten
movq $0, 0x20(%rsp) # 5. param _Inout_opt_ LPOVERLAPPED lpOverlapped
Řádek 547 ⟶ 557:
 
add $0x28, %rsp # uvolnenie rezervovaneho miesta
</syntaxhighlight>Ak chceme vypísať číslo v inej, napríklad šestnástkovej sústave, stačí deliť príslušným základom číselnej sústavy:<syntaxhighlight lang="gas" line="1" start="26">
mov $16, %rbx # zaklad ciselnej sustavy (delitel)
</syntaxhighlight>Tiež je potrebné vysporiadať sa so znakmi ':', ';', '<', '=', '>', '?' a '@', nachádzajúcimi sa v ASCII medzi znakmi '9' a 'A':<syntaxhighlight lang="gas" line="1" start="34">
cmp $10, %dl # zistime, ci zvysok je mensi nez 10
jl doDesat
add $7, %dl # medzi znakom '9' a 'A' lezi v ASCII sedem znakov, ktore potrebujeme pri prevode na znak 'A'-'F' preskocit
 
doDesat:
add $'0', %dl # pripocitanim 30h prevedie cislo 0-9 na znak '0'-'9'
</syntaxhighlight>