Files

277 lines
3.9 KiB
NASM

; -*- tab-width: 8 -*-
; MD5 checksum utility for x86 Linux, assembly version
; To build: nasm -f bin -O9 prog.x86.asm -o prog
%define @pie 0
BITS 32
%if @pie
ORG 0
%else
ORG 0x400000
%endif
%define @sys_exit 1
%define @sys_read 3
%define @sys_write 4
section .text
_code_seg:
_elf: db 7Fh,'ELF',1,1,1,0 ; e_ident
dq 0
dw 2+@pie ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd .ph-_elf ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw 0x34 ; e_ehsize
dw 0x20,1 ; e_phentsize, e_phnum
dw 0x28,0 ; e_shentsize, e_shnum
dw 0 ; e_shstrndx
.ph: dd 1 ; p_type
dd 0 ; p_offset
dd _code_seg ; p_vaddr
dd _code_seg ; p_paddr
dd _code_end-_code_seg ; p_filesz
dd _code_end-_code_seg ; p_memsz
dd 5, 0x1000 ; p_flags, p_align
_start:
%define @cos_hi 1133096 ; l
%define @cos_lo 128673 ; m
%define @sin_hi 1764692 ; o
%define @sin_lo 1171746 ; p
sub esp, 64*4
push @cos_hi
push @sin_hi
push @cos_lo
push @sin_lo
xor ebx, ebx
push -1 << (40 - 32)
push ebx
push ebx
push ebx
.4x: xor ebp, ebp
xor edi, edi
.4: mov eax, ebx
mov esi, ebx
and eax, 7
and esi, 3
add eax, esi
mov ecx, [esp+16+eax*2]
and esi, 1
mov eax, [esp+esi*8]
mul ecx
imul ecx, [esp+esi*8+4]
add edx, ecx
test bl, 1+4
jne .4a
sub edi, eax
sbb ebp, edx
jmp .4b
.4a: add edi, eax
adc ebp, edx
.4b: inc ebx
test bl, 1
jne .4
shrd edi, ebp, 21
sar ebp, 21
test bl, 2
jne .4
pop eax
pop edx
pop ecx
pop esi
push ebp
push edi
test bl, 4
je .4d
push edx
push eax
push esi
push ecx
jmp .4x
.4d: mov ecx, ebx
shrd edi, ebp, 8
sar ebp, 31
shr ecx, 3
xor edi, ebp
cmp ecx, 64+1
mov [esp+32+ecx*4-4], edi
jne .4x
add esp, 32
mov eax, ~0xefcdab89
cdq
push edx
push edx
mov ecx, ~0x67452301
push eax
push ecx
not eax
not ecx
push eax
push ecx
sub esp, 64+4
.2: mov edi, esp
xor eax, eax
lea ecx, [eax+16]
cld
rep stosd
test edx, edx
lea edx, [eax+64]
xchg ebx, eax ; 0 (stdin)
jne .2a
mov ecx, esp
%if @sys_read != @sys_write-1
lea edi, [ebx+@sys_read]
%endif
call _io
mov byte [ecx], 0x80
sub ecx, esp
shl ecx, 3
.2a: mov edi, esp
lea esi, [edi+64+4+16]
add [esi], ecx
adc [esi+4], ebx
cmp edx, 8
jb .2b
neg edx
add edi, 56
movsd
movsd
.2b: push edx
xor ebx, ebx
mov edx, esp
mov ecx, [edx+0x40+8]
mov edi, [edx+0x44+8]
mov esi, [edx+0x48+8]
mov ebp, [edx+0x4c+8]
.1: add ecx, [esp+64+16+16+ebx*4]
; ecx, edi, esi, ebp
%define PACK(a,b,c,d,e,f) (d<<15|c<<10|b<<5|a)<<4|e<<24|f
mov edx, ebx
shr edx, 5
mov eax, ebp
jne .1b
jc .1a
; 0: ((b^c)&a)^c
mov edx, PACK(7,12,17,22,1,0)
xor eax, esi
and eax, edi
xor eax, ebp
jmp .1e
.1a: ; 1: ((a^b)&c)^b
mov edx, PACK(5, 9,14,20,5,1)
mov eax, edi
xor eax, esi
and eax, ebp
jmp .1d
.1b: jc .1c
; 2: a^b^c
mov edx, PACK(4,11,16,23,3,5)
xor eax, edi
jmp .1d
.1c: ; 3: (~c|a)^b
mov edx, PACK(6,10,15,21,7,0)
not eax
or eax, edi
.1d: xor eax, esi
.1e: add eax, ecx
mov ecx, edx
shr ecx, 24
imul ecx, ebx
add ecx, edx
and ecx, 15
add eax, [esp+4+ecx*4]
mov ecx, ebx
and ecx, 3
lea ecx, [ecx+ecx*4+4]
shr edx, cl
mov ecx, edx
rol eax, cl
mov ecx, ebp ; a = d
mov ebp, esi ; d = c
mov esi, edi ; c = b
add edi, eax ; b += x
inc ebx
cmp ebx, 64
jne .1
mov edx, esp
add [edx+0x40+8], ecx
add [edx+0x44+8], edi
add [edx+0x48+8], esi
add [edx+0x4c+8], ebp
pop edx
test edx, edx
jge .2
xor edx, edx
mov edi, esp
.3: mov eax, edx
shr eax, 1
mov al, [esp+64+4+eax]
jc .3a
shr al, 4
.3a: and al, 15
cmp al, 10
jb .3b
add al, 'a'-'0'-10
.3b: add al, '0'
stosb
inc edx
cmp edx, 32
jne .3
mov al, 10
stosb
inc edx
mov ecx, esp
lea ebx, [edx-32] ; 1 (stdout)
%if @sys_read != @sys_write-1
lea edi, [ebx+@sys_write-1]
%endif
call _io
xor ebx, ebx ; exit code
lea eax, [ebx+@sys_exit]
int 0x80
_io:
%if @sys_read != @sys_write-1
mov eax, edi
%else
lea eax, [ebx+@sys_read]
%endif
push edx
int 0x80
pop edx
test eax, eax
jle .1
add ecx, eax
sub edx, eax
ja _io
cdq
.1: ret
_code_end: