Last active
March 7, 2023 19:11
-
-
Save tallpeak/5628c31c33aeb07b797032ed545b764d to your computer and use it in GitHub Desktop.
Character Frequency from stdin -- flat assembler version
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
format PE64 CONSOLE | |
entry start | |
include 'C:\util\fasmw17330\INCLUDE\WIN64a.INC' | |
section '.data' data readable writeable | |
;freq dq 256 dup(0) ; why waste 2kb in exe? | |
;freq equ rbp-8*256 ;stack allocation | |
define freq rbp-8*256 ;same as equ | |
header1 db "Top hex digits are the second digit of the character value", 10, "Left-side hex numbers are the first digit of the character value", 10, "numbers in the table are the frequency of each character found in stdin.", 10, 0 | |
header2 db " 0 1 2 3 4 5 6 7 8 9 a b c d e f",13,10,0 | |
header3 db " =======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", "=======", 10, 0 | |
fmt db "%7d", 0 | |
fmt2 db "%02x: ", 0 | |
section '.text' code readable executable | |
start: | |
push rbp | |
mov rbp, rsp | |
sub rsp, 32+8*256 ; stack allocate the freq table | |
; Clear the frequency table | |
cld | |
lea rsi,[freq] | |
mov rdi,rsi | |
mov rcx, 256 | |
xor rax,rax | |
rep stosq | |
; Print the header | |
lea rcx, [header1] | |
call [printf] | |
lea rcx, [header2] | |
call [printf] | |
lea rcx, [header3] | |
call [printf] | |
;_setmode(_fileno(stdin),_O_BINARY) | |
mov rcx, 0 ; _fileno(stdin) == -11 | |
mov rdx, 0x8000 ; _O_BINARY == 0x8000 | |
call [setmode] | |
read_loop: | |
; Read a character from stdin | |
xor rcx,rcx | |
xor rax,rax | |
call [getchar] | |
cmp eax, -1 | |
je end_read_loop | |
; Increment the frequency table for the character | |
movzx rcx, al | |
inc qword [freq + rcx*8] | |
jmp read_loop | |
end_read_loop: | |
; Print the frequency table | |
xor rsi,rsi | |
print_loop: | |
; Print left header | |
lea rcx, [fmt2] | |
mov rdx,rsi | |
call [printf] | |
inner_loop: | |
; Print the frequency for the current character | |
mov rdx, [freq + rsi*8] | |
lea rcx, [fmt] | |
call [printf] | |
inc rsi | |
mov rcx,rsi | |
and rcx,15 | |
jnz inner_loop | |
; Print a newline | |
mov rcx, 0x0d | |
call [putchar] | |
mov rcx, 0x0a | |
call [putchar] | |
cmp rsi, 256 | |
jb print_loop | |
; Return 0 | |
xor rax, rax | |
add rsp, 32+8*256 | |
pop rbp | |
invoke ExitProcess,0 | |
section '.idata' import data readable | |
library msvcrt, 'msvcrt.dll',\ | |
kernel32, 'kernel32.dll' | |
import msvcrt, \ | |
printf, 'printf',\ | |
getchar, 'getchar',\ | |
putchar, 'putchar',\ | |
setmode, '_setmode' | |
import kernel32, \ | |
ExitProcess, 'ExitProcess', \ | |
SetLastError, 'SetLastError' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment