Programovanie v assembleri vo Windows x64 (x86-64): Rozdiel medzi revíziami
Smazaný obsah Přidaný obsah
Bez shrnutí editace Značka: editor wikitextu 2017 |
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+
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 #
# kompilacia:
# as
# linkovanie:
# ld -e main -s
# alternativna kompilacia+linkovanie:
# gcc -m64 -nostartfiles -Wl,-emain -o
.global main
.section .data
buffer: .ascii "
enter: .ascii "h\
lpNumberOfBytesWritten: .long 0▼
BUFFER_LEN = enter - buffer
NEWLINE_LEN = lpNumberOfBytesWritten - enter
▲lpNumberOfBytesWritten: .long 0
Řádek 507 ⟶ 511:
main:
IntToHex:
mov $1234567890, %rax # cislo, ktore potrebujeme vypisat (delenec)
mov $
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+
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>
|