langsmoke/ref_x64

319 lines
5.0 KiB
Plaintext

format ELF64 executable
use64
entry _start
load_elf:
xor esi, esi
mov edi, self
push sys_open
pop rax
syscall
; Obtain the length: seek to back.
mov r8, rax
mov rdi, r8
push sys_lseek
pop rax
syscall
; Call memfd_create, call with MFD_CLOEXEC.
mov edi, empty
push 1
pop rsi
push sys_memfd_create
pop rax
syscall
; Copy the file contents to the memfd using sendfile.
mov edx, size
mov r9, rax
mov rdi, rax
mov rsi, r8
sub r10d, SIZE
push sys_sendfile
pop rax
syscall
; Close the file descriptor we hold to our own binary.
push sys_close
pop rax
mov rdi, r8
syscall
; Bravely assume that the memfd descriptor number is a single digit.
; This might or might not work all of the times, but improving upon
; this is trivially beyond the scope of this post.
add r9d, 48
mov BYTE [memfd_path + 14], r9b
ret
; Compute the adler32 checksum.
; Input:
; - EDI => initial checksum value.
; - RCX => input buffer
; - RDX => input size
adler32:
; eax = high(edi), esi = low(edi)
mov eax, edi
shr eax, 16
movzx esi, di
; load the pointer to the end of the data
lea r10, [rcx + rdx]
test rdx, rdx
je .terminate
; Check if the lowest two bits of the input pointer are aligned to 16 bytes.
test cl, 15
jne .unaligned
.aligned:
mov rdx, r10
mov r8, r10
sub rdx, rcx
and edx, 31
sub r8, rdx
cmp rcx, r8
je .process_remaining
mov r9d, 0x80078071
; The initial vector values.
pxor xmm1, xmm1
movdqu xmm8, [.V32]
movdqu xmm7, [.V24]
movdqu xmm6, [.V16]
movdqu xmm5, [.V8]
.chunk_loop:
mov rdx, r8
sub rdx, rcx
mov edi, 4096
cmp rdx, rdi
cmova rdx, rdi
pxor xmm0, xmm0
pxor xmm13, xmm13
pxor xmm4, xmm4
pxor xmm11, xmm11
pxor xmm10, xmm10
pxor xmm9, xmm9
mov rdi, rdx
mov rdx, rcx
and rdi, 0xFFFFFFFFFFFFFFE0
; Define the end of the chunk as the input pointer + chunk size.
add rcx, rdi
; high += low * chunk_size
imul edi, esi
add edi, eax
.inner_chunk_loop:
movdqa xmm3, [rdx]
movdqa xmm2, [rdx + 16]
paddd xmm13, xmm0
movdqa xmm12, xmm3
psadbw xmm12, xmm1
paddd xmm12, xmm0
movdqa xmm0, xmm2
psadbw xmm0, xmm1
paddd xmm0, xmm12
movdqa xmm12, xmm3
punpckhbw xmm3, xmm1
punpcklbw xmm12, xmm1
paddw xmm11, xmm3
paddw xmm4, xmm12
movdqa xmm3, xmm2
punpckhbw xmm2, xmm1
punpcklbw xmm3, xmm1
paddw xmm9, xmm2
paddw xmm10, xmm3
mov edi, 0x80078071
mod0xFFF1 rdi, 47, esi, dx
pop rdi
pop rdi
pop rdi
mov esi, sb
mov rdi, rax
mov eax, fstat
pop r8
xor r9d, r9d
xor edi, edi
mov eax, mmap
mov edx, 1
mov r10d, edx
mov rsi, [sb + 48]
syscall
main:
push RBP
mov RAX, 0
mov RCX, 0
mov RBX, 0
INPUT_ARRAY:
cmp RCX, 5
jz DONE
mov [cnt], RCX
mov RAX, 0
mov RDI, fmt_in
mov RSI, a
call scanf
mov RAX, [a]
mov RCX, [cnt]
mov [array+RCX*8], RAX
mov [array2+RCX*8], RAX
add RBX, [a]
inc RCX
jmp INPUT_ARRAY
DONE:
mov RAX, 0
mov RCX, 0
mov RBX, 0
OUTER_LOOP:
cmp RCX, 5
jge END_LOOP
mov [cnt], RCX
mov RAX, [array+RCX*8]
INNER_LOOP:
inc RCX
cmp RCX, 5
jz OK
cmp RAX, [array+RCX*8]
jle INNER_LOOP
xchg RAX, [array+RCX*8]
jmp INNER_LOOP
OK:
mov RCX, [cnt]
mov [array+RCX*8], RAX
inc RCX
jmp OUTER_LOOP
END_LOOP:
mov RAX, 0
mov RBX, 0
mov RCX, 0
mov RDI, fmt_out
call printf
mov RAX, 0
mov RBX, 0
mov RCX, 0
PRINT_ARRAY:
cmp RCX, 5
jz END
mov RAX, [array+RCX*8]
inc RCX
mov [cnt], RCX
mov RDI, fmt
mov RSI, RAX
call printf
mov RCX, [cnt]
jmp PRINT_ARRAY
END:
mov RAX, 0
pop RBP
ret
main:
push RBP
mov RAX, 0
mov RSI, a
mov RDI, fmt_in
call scanf
mov RAX, 0
mov RSI, b
mov RDI, fmt_in
call scanf
OUTER_LOOP:
mov RCX, [a]
cmp RCX, [b]
jg END_OUTER_LOOP
mov RAX, 0
mov RCX, 2
mov RBX, 0
mov RAX , [a]
cmp RAX, 2
je PRIME
cmp RAX, 1
je PRIME
WHILE:
mov RAX, [a]
mov RDX, 0
mov RBX, RCX
idiv RBX
cmp RDX, 0
jz NOT_PRIME
inc RCX
cmp RCX, [a]
jz PRIME
jmp WHILE
PRIME:
mov RCX, [size]
mov RAX, [a]
mov [array + RCX*8], RAX
inc RCX
mov [size], RCX
mov RCX, [a]
inc RCX
mov [a], RCX
jmp OUTER_LOOP
NOT_PRIME:
mov RCX, [a]
inc RCX
mov [a], RCX
jmp OUTER_LOOP
END_OUTER_LOOP:
mov RAX, 0
mov RBX, 0
mov RCX, 0
mov RDI, fmt_out2
call printf
mov RAX, 0
mov RBX, 0
mov RCX, 0
PRINT_ARRAY:
cmp RCX, [size]
jz LAST
test RCX, 1
jz INC_ODD
jmp INC_EVEN
DONE:
mov RAX, [array+RCX*8]
inc RCX
mov [cnt], RCX
mov RDI, fmt_out
mov RSI, RAX
call printf
mov RDI, spc
call printf
mov RCX, [cnt]
jmp PRINT_ARRAY
INC_ODD:
mov RAX, [array+RCX*8]
add RAX, [odd_pos]
mov [odd_pos], RAX
jmp DONE
INC_EVEN:
mov RAX, [array+RCX*8]
add RAX, [even_pos]
mov [even_pos], RAX
jmp DONE
LAST:
mov RDI, new_line
call printf
mov RAX, [even_pos]
sub RAX, [odd_pos]
mov RDI, fmt_out3
mov RSI, RAX
call printf
mov RDI, new_line
call printf
mov RAX, 0
mov RAX, 0
pop RBP
ret