This commit is contained in:
julianb0 2019-08-03 17:41:44 +02:00
parent 334053b24c
commit 89ed8fdc0d
No known key found for this signature in database
GPG Key ID: 9C7ACF0C053FB8A1
30 changed files with 305 additions and 373 deletions

View File

@ -13,7 +13,7 @@ from collections import OrderedDict
#print("k-as command line: '{}'".format(sys.argv))
WANT_DISASM = True
WANT_DISASM = False
if len(sys.argv) != 5:
print("Usage: {} (source file) (memory entry point) (output file) (symbols file)"
@ -449,8 +449,6 @@ def parse_instr(line):
else:
params = None
fellthrough = False
size = 2
# Byte 2 (rep|lock|0|cond)
@ -486,6 +484,13 @@ def parse_instr(line):
tok = params.split(',')
# 'call' special case... temporary
if instr_name == 'call':
if len(tok) == 2:
instr_name = 'xcall2'
elif len(tok) == 3:
instr_name = 'xcall3'
#
# Parse operands
#
@ -540,8 +545,6 @@ def parse_instr(line):
print("Missing access length modifier: {}".format(line))
leave(1)
instr_name += "_m"
# cheap way of getting [reg - imm] to work
word = word.replace('-', '+ -')
@ -668,7 +671,6 @@ def parse_instr(line):
# immediates
if is_number(word):
n = int(word, base=0)
instr_name += "_i"
if n < 0 or n > 0xFFFFFFFF:
size += 9
@ -695,7 +697,6 @@ def parse_instr(line):
# register
elif word in pregs:
size += 1
instr_name += "_r"
instr_args += word
continue
@ -703,7 +704,6 @@ def parse_instr(line):
# ModRM + imm
size += 5
instr_name += "_i"
instr_args += "%%imm8 {} ".format(fmts["imm32"])
if word[0] == '.':

View File

@ -32,10 +32,9 @@ doprnt:
.print_regular:
b.z r12, r13, .check_modf
mov ax0, b[r12]
call .doput
call .doput, b[r12]
add r12, r12, 1
inc r12, 1
jmp .print_regular
.check_modf:
@ -45,7 +44,7 @@ doprnt:
; we did find a modifier / '%'
mov rax, b[r12+1]
add r12, r12, 2
inc r12, 2
b.z rax, 's', .modf_s
b.z rax, 'c', .modf_c
@ -62,24 +61,23 @@ doprnt:
.modf_s:
; get string address
mov r13, q[r14]
add r14, r14, 8
inc r14, 8
cmp r13, zero
jmp.z .nullstring
b.z r13, zero, .nullstring
.print_string:
mov ax0, b[r13]
cmp ax0, zero
jmp.z .main_loop
b.z ax0, zero, .main_loop
add r13, r13, 1
inc r13, 1
call .doput
jmp .print_string
.modf_c:
mov ax0, q[r14]
add r14, r14, 8
call .doput
call .doput, q[r14]
inc r14, 8
jmp .main_loop
.modf_p:
@ -105,23 +103,21 @@ doprnt:
.print_number:
; allocate itoa conversion buffer
sub rsp, rsp, 80
dec rsp, 80
mov r13, rsp
; assume modifier already set up ax2
mov ax0, rsp
mov ax1, q[r14]
call itoa
add r14, r14, 8
call itoa, rsp, q[r14]
inc r14, 8
.print_itoa_buf:
mov ax0, b[r13]
cmp ax0, zero
add.z rsp, rsp, 80
inc.z rsp, 80
jmp.z .main_loop
add r13, r13, 1
inc r13, 1
call .doput
jmp .print_itoa_buf
@ -164,7 +160,7 @@ doprnt:
;
.doput:
; update print count
add r16, r16, 1
inc r16, 1
; if n==0, don't print
; we follow the C convention that sprintf()-like functions
@ -174,7 +170,7 @@ doprnt:
ret.z
; if n>0, decrement n and print
sub r15, r15, 1
dec r15, 1
call r17
; did putc fail?

View File

@ -44,15 +44,15 @@ ltostr:
b.a rdx, 9, .nondec ; rdx > 9 ?
add rdx, rdx, '0'
inc rdx, '0'
jmp .next
.nondec:
add rdx, rdx, 55 ; 'A' - 10
inc rdx, 55 ; 'A' - 10
.next:
mov b[ax0], rdx
add ax0, ax0, 1
inc ax0, 1
div ax1, ax1, ax2
jmp .conv

View File

@ -39,12 +39,12 @@ strtoq:
.skip_spc:
cmp b[rdx], ' '
add.z rdx, rdx, 1
inc.z rdx, 1
jmp.z .skip_spc
; skip +
cmp b[rdx], '+'
add.z rdx, rdx, 1
inc.z rdx, 1
; signed?
cmp ax2, zero
@ -53,7 +53,7 @@ strtoq:
; parse '-'
cmp b[rdx], '-'
add.z rdx, rdx, 1
inc.z rdx, 1
mov.z rsi, 1
mov.nz rsi, zero
@ -64,7 +64,7 @@ strtoq:
; base prefix?
b.nz b[rdx], '0', .main_loop
add rdx, rdx, 1
inc rdx, 1
movzx rcx, b[rdx]
; "0x"/"0b" prefix
@ -81,7 +81,7 @@ strtoq:
; if not, leave rax = 0 and *rdx = 'x'
b.nz ax1, 16, .done
; else
add rdx, rdx, 1
inc rdx, 1
jmp .main_loop
.parsed_0b:
@ -89,7 +89,7 @@ strtoq:
; if not, leave rax = 0 and *rdx = 'b'
b.nz ax1, 2, .done
; else
add rdx, rdx, 1
inc rdx, 1
jmp .main_loop
.base_0:
@ -98,15 +98,15 @@ strtoq:
cmp b[rdx], '0'
mov.nz ax1, 10
jmp.nz .main_loop
add rdx, rdx, 1
inc rdx, 1
cmp b[rdx], 'x'
add.z rdx, rdx, 1
inc.z rdx, 1
mov.z ax1, 16
jmp.z .main_loop
cmp b[rdx], 'b'
add.z rdx, rdx, 1
inc.z rdx, 1
mov.z ax1, 2
jmp.z .main_loop
@ -114,23 +114,23 @@ strtoq:
.main_loop:
movzx rcx, b[rdx]
add rdx, rdx, 1
inc rdx, 1
cmp rcx, '0'
jmp.b .done
cmp.ae rcx, '9'
sub.be rcx, rcx, '0'
dec.be rcx, '0'
jmp.be .next
cmp rcx, 'A'
cmp.ae rcx, 'Z'
sub.be rcx, rcx, 55 ; 'A' - 10
dec.be rcx, 55 ; 'A' - 10
jmp.be .next
cmp rcx, 'a'
jmp.b .next
cmp.ae rcx, 'z'
sub.be rcx, rcx, 87 ; 'a' - 10
dec.be rcx, 87 ; 'a' - 10
jmp.be .next
.next:
@ -138,7 +138,7 @@ strtoq:
b.ae rcx, ax1, .done
mul rax, rax, ax1
add rax, rax, rcx
inc rax, rcx
jmp .main_loop
.done:

View File

@ -36,7 +36,7 @@ DaysInYear:
jmp.cxnz .end
.leap:
add rax, rax, 1
inc rax, 1
.end:
ret

View File

@ -10,11 +10,7 @@ memcpy:
.l:
sub rdx, ax2, rcx
mov rax, b[ax1+rdx]
mov b[ax0+rdx], rax
mov b[ax0+rdx], b[ax1+rdx]
loop .l
ret

View File

@ -22,11 +22,11 @@ strcmp:
add rbx, rax, rdx
jmp.bxz .r
add rcx, rcx, 1
inc rcx, 1
jmp .l
.r:
sub rax, rax, rdx
dec rax, rdx
ret
;
@ -43,11 +43,11 @@ strncmp:
cmp rax, rdx
jmp.nz .r
add ax0, ax0, 1
add ax1, ax1, 1
inc ax0, 1
inc ax1, 1
loop .l
.r:
sub rax, rax, rdx
dec rax, rdx
ret

View File

@ -11,8 +11,8 @@ strcpy:
ret.cxz
add ax0, ax0, 1
add ax1, ax1, 1
inc ax0, 1
inc ax1, 1
jmp .l
@ -24,11 +24,10 @@ strncpy:
ret.cxz
.l:
mov rax, b[ax1]
mov b[ax0], rax
mov b[ax0], b[ax1]
add ax0, ax0, 1
add ax1, ax1, 1
inc ax0, 1
inc ax1, 1
loop .l
ret
@ -46,8 +45,8 @@ strnzcpy:
jmp.axz .r
add ax0, ax0, 1
add ax1, ax1, 1
inc ax0, 1
inc ax1, 1
loop .l

View File

@ -18,20 +18,19 @@ strrev:
; the null terminator
mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero
sub ax1, ax1, 1
dec ax1, 1
.2:
; copy, going backward though str
; and forward through buf
mov rax, b[ax1]
mov b[ax0], rax
mov b[ax0], b[ax1]
cmp ax1, rsi
mov.z b[ax0+1], zero
ret.z
add ax0, ax0, 1
sub ax1, ax1, 1
inc ax0, 1
dec ax1, 1
jmp .2
@ -50,18 +49,16 @@ strrev2:
; the null terminator
mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero
sub ax1, ax1, 1
dec ax1, 1
; increase ax0 while decreasing ax1, performing exchanges
.2:
b.ae ax0, ax1, .3
mov rax, b[ax1]
xchg rax, b[ax0]
mov b[ax1], rax
xchg b[ax0], b[ax1]
add ax0, ax0, 1
sub ax1, ax1, 1
inc ax0, 1
dec ax1, 1
jmp .2
.3:

View File

@ -5,9 +5,7 @@ TrapHandlers.prolog:
mov rbp, rsp
; nx0 = caller's cr2
mov ax0, r14
mov ax1, $cr2
call RFS.LoadReg
call RFS.LoadReg, r14, $cr2
; we don't preserve the r12 we got
mov r12, rax

View File

@ -9,10 +9,8 @@ trap0_handler:
jmp TrapHandlers.prolog
.text:
mov ax0, r14
mov ax1, $rax
call RFS.LoadReg
call RFS.LoadArgs
call RFS.LoadReg, r14, $rax
call RFS.LoadArgs, r14
b.z rax, zero, .handle_Shutdown
b.z rax, Sys.Exit, .handle_Exit
@ -66,7 +64,7 @@ trap0_handler:
call RFS.StoreReg, zero, $cr0
mov rcx, CMDCOM_LOADP
sub rcx, rcx, 0x100000
dec rcx, 0x100000
; Code offset
mov ax2, rcx
@ -87,17 +85,17 @@ trap0_handler:
; Disk API
;
.handle_FindFirst:
add ax0, ax0, r12
inc ax0, r12
call DISK.FindFirst
jmp .fini
.handle_FindNext:
add ax0, ax0, r12
inc ax0, r12
call DISK.FindNext
jmp .fini
.handle_OpenFile:
add ax0, ax0, r12
inc ax0, r12
call DISK.OpenFile
jmp .fini
@ -106,7 +104,7 @@ trap0_handler:
jmp .fini
.handle_ReadFile:
add ax1, ax1, r12
inc ax1, r12
call DISK.ReadFile
jmp .fini

View File

@ -21,7 +21,7 @@ InitSyscalls:
call RFS.StoreReg
mov ax1, ax0
add ax0, ax0, 255 # TRAP no. (ax0 - 1)
inc ax0, 255 # TRAP no. (ax0 - 1)
call IDT.AddHandler
ret

View File

@ -10,9 +10,7 @@ builtins.dir:
push r12
mov r12, zero # no. of files found
mov rcx, STRLEN_MAX
mov rdx, .dirmsg
prns.rep.nz rdx
call print, .dirmsg
.dirmsg = "Directory of C:\\\n\n"
@ -34,7 +32,7 @@ builtins.dir:
jmp.axz .end
; found something
add r12, r12, 1
inc r12, 1
; separate extension from file name
mov rcx, NAME_MAX
@ -48,13 +46,13 @@ builtins.dir:
; calculate where to put extension
sub rdi, rsi, .buf
sub rdi, rdi, 1
dec rdi, 1
.ext_pad:
; print at least 11 non-space characters before extension
b.ae rdi, 11, .print_ext
prn ' '
add rdi, rdi, 1
inc rdi, 1
jmp .ext_pad
.print_ext:
@ -69,10 +67,9 @@ builtins.dir:
b.z b[rsi], 0, .print_ext.2
; print and decrease rcx, unless it's already 0
mov rbx, b[rsi]
prn rbx
add rsi, rsi, 1
sub.cxnz rcx, rcx, 1
prn b[rsi]
inc rsi, 1
dec.cxnz rcx, 1
jmp .print_ext.1
@ -84,9 +81,8 @@ builtins.dir:
.print_bytes:
; print file size in bytes
prn ' '
prn ' '
prn ' '
mov rcx, 3
prn.rep ' '
shr rax, rdx, 10
and rdx, rdx, 1023
@ -94,7 +90,7 @@ builtins.dir:
push rdx
push rax
call printf, .bytesstr
add rsp, rsp, 16
inc rsp, 16
.bytesstr = "%d kilobytes + %d bytes"
@ -106,7 +102,7 @@ builtins.dir:
.end:
push r12
call printf, .endstr1
add rsp, rsp, 8
inc rsp, 8
call print, .endstr2

View File

@ -41,7 +41,7 @@ main:
jmp.cxz .input_loop ; no
; yes, delete it
sub rcx, rcx, 1
dec rcx, 1
add rdx, rcx, argbuf
mov b[rdx], zero
@ -63,7 +63,7 @@ main:
; add character to buffer and increase iterator (rcx)
add rdx, rcx, argbuf
mov b[rdx], rax
add rcx, rcx, 1
inc rcx, 1
; another one
jmp .input_loop
@ -87,7 +87,7 @@ main:
; skip spaces
cmp rcx, ' '
add.z rsi, rsi, 1
inc.z rsi, 1
jmp.z .next_space
; if we're here, we found a
@ -105,17 +105,16 @@ main:
; how much do we copy?
sub rcx, rdx, argbuf
jmp.cxz .detect_builtin
sub rcx, rcx, 1
dec rcx, 1
mov rdi, argbuf
mov rsi, argv0
.copy_loop:
mov rax, b[rdi]
mov b[rsi], rax
mov b[rsi], b[rdi]
add rdi, rdi, 1
add rsi, rsi, 1
inc rdi, 1
inc rsi, 1
loop .copy_loop
@ -185,7 +184,7 @@ main:
call printf, .datefmt
add rsp, rsp, 40
inc rsp, 40
jmp .print_prompt
@ -255,7 +254,7 @@ main:
push b[rax+1]
push b[rax+2]
call printf, .timefmt
add rsp, rsp, 24
inc rsp, 24
jmp .print_prompt
@ -307,7 +306,7 @@ main:
push q[argv1pos]
push argv0
call printf, .fnf_errmsg
add rsp, rsp, 16
inc rsp, 16
jmp .print_prompt
@ -317,7 +316,7 @@ main:
push q[argv1pos]
push argv0
call printf, .ef_errmsg
add rsp, rsp, 16
inc rsp, 16
jmp .print_prompt
@ -327,7 +326,7 @@ main:
push q[argv1pos]
push argv0
call printf, .cno_errmsg
add rsp, rsp, 16
inc rsp, 16
jmp .print_prompt

View File

@ -12,7 +12,7 @@
#
# Preserves all flags
#
or r r ri
or 3
#
# Bitwise AND operation
@ -21,7 +21,7 @@ or r r ri
#
# Preserves all flags
#
and r r ri
and 3
#
# Bitwise XOR operation
@ -30,7 +30,7 @@ and r r ri
#
# Preserves all flags
#
xor r r ri
xor 3
#
# Logical left/right shift (SHL/SHR)
@ -40,8 +40,8 @@ xor r r ri
#
# Preserves all flags
#
shl r r ri
shr r r ri
shl 3
shr 3
#
# Arithmetical left/right shift (SAL/SAR)
@ -51,8 +51,8 @@ shr r r ri
#
# Preserves all flags
#
sal r r ri
sar r r ri
sal 3
sar 3
#---------------------------------------------------------------------------#
# Arithmetic instructions #
@ -67,8 +67,7 @@ sar r r ri
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
cmp r ri
cmp m ri
cmp 2
#
# Arithmetical ADD operation
@ -79,8 +78,9 @@ cmp m ri
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
add r r ri
addf r r ri
inc 2
add 3
addf 3
#
# Arithmetical SUB operation
@ -91,8 +91,9 @@ addf r r ri
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
sub r r ri
subf r r ri
dec 2
sub 3
subf 3
#
# Arithmetical ADD/SUB operation, with carry/overflow
@ -104,8 +105,8 @@ subf r r ri
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
adcx r r ri
sbbx r r ri
adcx 3
sbbx 3
#
# Arithmetical MUL operation
@ -115,8 +116,8 @@ sbbx r r ri
# Preserves ZF and SF
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
#
mul r r ri
mulf r r ri
mul 3
mulf 3
# Arithmetical unsigned MUL operation
#
@ -125,7 +126,7 @@ mulf r r ri
#
# Preserves all flags
#
mulhi r r ri
mulhi 3
# Arithmetical signed MUL operation
#
@ -134,7 +135,7 @@ mulhi r r ri
#
# Preserves all flags
#
imulhi r r ri
imulhi 3
#
# Arithmetical unsigned DIV operation
@ -143,7 +144,7 @@ imulhi r r ri
#
# Preserves all flags
#
div r r ri
div 3
#
# Arithmetical signed DIV operation
@ -152,7 +153,7 @@ div r r ri
#
# Preserves all flags
#
idiv r r ri
idiv 3
#
# Arithmetical modulo operation (REM)
@ -161,5 +162,5 @@ idiv r r ri
#
# Preserves all flags
#
rem r r ri
rem 3

View File

@ -10,7 +10,7 @@
#
# RIP = $1
#
jmp ri
jmp 1
#
# RCX-dependent jump (LOOP) instruction
@ -20,7 +20,7 @@ jmp ri
# RIP = $1
# FI
#
loop ri
loop 1
#
# Conditional absolute jumps (B)
@ -38,7 +38,7 @@ loop ri
#
# Suffixing B with the REP suffix results in undefined behavior
#
b rm ri ri
b 3
#---------------------------------------------------------------------------#
@ -51,9 +51,9 @@ b rm ri ri
# PUSH(RIP)
# JMP(RIP)
#
call ri
call i ri
call i ri ri
call 1
xcall2 2
xcall3 3
#
# Return to caller (RET)
@ -69,7 +69,7 @@ ret
# RBP = RSP
# RSP = RSP - $1
#
enter i
enter 1
#
# Leave stack frame (LEAVE)
@ -85,7 +85,7 @@ leave
# RSP = RSP - 8
# *RSP = $1
#
push rim
push 1
#
# POP value from stack
@ -93,7 +93,7 @@ push rim
# $1 = *RSP
# RSP = RSP + 8
#
pop r
pop 1
#---------------------------------------------------------------------------#
# Movement instructions #
@ -111,31 +111,30 @@ pop r
#
# Preserves all flags
#
lea r m
lea 2
#
# Move data (MOV) instruction
#
# $1 = SignExtend($2)
#
mov r rim
mov m ri
mov 2
#
# Load from memory with zero-extension (MOVSX/MOVZX) instruction
#
# $1 = ZeroExtend($2)
#
movzx r m
movzx 2
#
# Move with sign-extension (MOVSXx) instruction
#
# $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1)
#
movsxb r r
movsxw r r
movsxd r r
movsxb 2
movsxw 2
movsxd 2
#
# Exchange (XCHG) instruction
@ -144,5 +143,5 @@ movsxd r r
# $1 = $2
# $2 = $_
#
xchg r rm
xchg 2

View File

@ -38,14 +38,14 @@ into
#
# Get timestamp in µseconds
#
utime r r
utime 2
#
# $1 = seconds since start of month
# $2 = current month
# $3 = current year
#
ytime r r r
ytime 3
#
# Clear all GPR registers except RBP/RSP
@ -61,9 +61,9 @@ cls
#
# Change endianness
#
bswap r r
wswap r r
dswap r r
bswap 2
wswap 2
dswap 2
#---------------------------------------------------------------------------#
# I/O instructions #
@ -72,7 +72,7 @@ dswap r r
#
# Send a character to standard output (PRN)
#
prn ri
prn 1
#
# Print a string to standard output (PRN)
@ -89,10 +89,10 @@ prn ri
# FI
#
#
prns r
prns 1
#
# Scan a character from standard input (SCAN)
#
scan r
scan 1

View File

@ -15,10 +15,10 @@
# %str = %str - sizeof(x)
# FI
#
stosb r ri
stosw r ri
stosd r ri
stosq r ri
stosb 2
stosw 2
stosd 2
stosq 2
#
# Scan string for a particular value (SCASx)
@ -42,10 +42,10 @@ stosq r ri
# - Does not move past the value when found
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
#
scasb r ri
scasw r ri
scasd r ri
scasq r ri
scasb 2
scasw 2
scasd 2
scasq 2
#---------------------------------------------------------------------------#

View File

@ -48,7 +48,7 @@ hlt
# #ILL if $1 > 255
# #($1+256) otherwise
#
trap ri
trap 1
#
# Return from exception/interrupt (IRET)
@ -79,7 +79,7 @@ sti
# Throws:
# #SYS if not in supervisor mode
#
devctl r r
devctl 2
#
# Call a device-defined function slot of device (IOCALL)
@ -89,5 +89,5 @@ devctl r r
# Throws:
# #SYS if not in supervisor mode
#
iocall ri ri
iocall 2

View File

@ -8,27 +8,32 @@
//----------------------------------------------------------------------------//
IMPL_START(or) { *r1 = p2->val | p3->val; return 1; }
IMPL_START(and) { *r1 = p2->val & p3->val; return 1; }
IMPL_START(xor) { *r1 = p2->val ^ p3->val; return 1; }
IMPL_START(or) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; }
IMPL_START(and) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; }
IMPL_START(xor) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ p3->val; return 1; }
//----------------------------------------------------------------------------//
IMPL_START(shl) { *r1 = p2->val << p3->val; return 1; }
IMPL_START(shr) { *r1 = p2->val >> p3->val; return 1; }
IMPL_START(sal) { *r1 = (ulong)((long)p2->val << (long)p3->val); return 1; }
IMPL_START(sar) { *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; }
IMPL_START(shl) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; }
IMPL_START(shr) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; }
IMPL_START(sal) { SRCP(p2); SRCP(p3); *r1 = (ulong)((long)p2->val << (long)p3->val); return 1; }
IMPL_START(sar) { SRCP(p2); SRCP(p3); *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; }
//----------------------------------------------------------------------------//
IMPL_START(add) { *r1 = p2->val + p3->val; return 1; }
IMPL_START(addf) { COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; }
IMPL_START(inc) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; }
IMPL_START(add) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; }
IMPL_START(addf) { SRCP(p2); SRCP(p3); COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; }
IMPL_START(sub) { *r1 = p2->val - p3->val; return 1; }
IMPL_START(subf) { COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; }
IMPL_START(dec) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; }
IMPL_START(sub) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; }
IMPL_START(subf) { SRCP(p2); SRCP(p3); COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; }
IMPL_START(adcx)
{
SRCP(p2);
SRCP(p3);
p3->val += !!(R(RFX)&CF);
COMPARE_ADD(p2->val, p3->val);
*r1 = p2->val + p3->val;
@ -38,6 +43,9 @@ IMPL_START(adcx)
IMPL_START(sbbx)
{
SRCP(p2);
SRCP(p3);
p3->val += !!(R(RFX)&CF);
COMPARE_SUB(p2->val, p3->val);
*r1 = p2->val - p3->val;
@ -47,11 +55,14 @@ IMPL_START(sbbx)
//----------------------------------------------------------------------------//
IMPL_START(mul) { *r1 = p2->val * p3->val; return 1; }
IMPL_START(rem) { *r1 = p2->val % p3->val; return 1; }
IMPL_START(mul) { SRCP(p2); SRCP(p3); *r1 = p2->val * p3->val; return 1; }
IMPL_START(rem) { SRCP(p2); SRCP(p3); *r1 = p2->val % p3->val; return 1; }
IMPL_START(div)
{
SRCP(p2);
SRCP(p3);
if (!p3->val)
_except(ctx, E_DIV, "DIV by 0");
*r1 = p2->val / p3->val;
@ -61,6 +72,9 @@ IMPL_START(div)
IMPL_START(idiv)
{
SRCP(p2);
SRCP(p3);
if (!p3->val)
_except(ctx, E_DIV, "IDIV by 0");
@ -81,12 +95,18 @@ static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
IMPL_START(mulhi)
{
SRCP(p2);
SRCP(p3);
__unsigned_multiply128(p2->val, p3->val, r1, r2);
return 2;
}
IMPL_START(mulf)
{
SRCP(p2);
SRCP(p3);
ulong tmp;
__unsigned_multiply128(p2->val, p3->val, &tmp, r1);
R(RFX) = p2->val ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
@ -106,6 +126,9 @@ static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
IMPL_START(imulhi)
{
SRCP(p2);
SRCP(p3);
__signed_multiply128(p2->val, p3->val, r1, r2);
return 2;
}

View File

@ -5,25 +5,6 @@
from tempfile import TemporaryFile
def getflag(s):
if s == "r":
return "P_REG"
if s == "i":
return "P_IMM"
if s == "m":
return "P_MEM"
return "__FLAG_ERROR__"
def doprnt(fp, i, p1, p2, p3):
for c1 in p1:
for c2 in p2:
for c3 in p3:
fp.write("{} {} {} {}".format(i, c1, c2, c3).strip())
fp.write('\n')
def parse_1(fi, fp):
global count
@ -41,36 +22,7 @@ def parse_1(fi, fp):
parse_1(fi2, fp)
continue
tok = line.split()
if len(tok) == 0:
continue
i = tok[0]
if len(tok) == 1:
doprnt(fp, i, ' ', ' ', ' ')
continue
if len(tok) == 2:
p = tok[1]
doprnt(fp, i, p, ' ', ' ')
continue
if len(tok) == 3:
p1 = tok[1]
p2 = tok[2]
doprnt(fp, i, p1, p2, ' ')
continue
assert(len(tok) == 4)
p1 = tok[1]
p2 = tok[2]
p3 = tok[3]
doprnt(fp, i, p1, p2, p3)
fi.close()
fp.write("{}\n".format(line))
def parse_2(fp):
global count
@ -89,41 +41,19 @@ def parse_2(fp):
if len(tok) == 1:
name = tok[0]
p1 = "NOPRM"
p2 = "NOPRM"
p3 = "NOPRM"
elif len(tok) == 2:
name = "{}_{}".format(tok[0], tok[1])
p1 = getflag(tok[1])
p2 = "NOPRM"
p3 = "NOPRM"
elif len(tok) == 3:
name = "{}_{}_{}".format(tok[0], tok[1], tok[2])
p1 = getflag(tok[1])
p2 = getflag(tok[2])
p3 = "NOPRM"
elif len(tok) == 4:
name = "{}_{}_{}_{}".format(tok[0], tok[1], tok[2], tok[3])
p1 = getflag(tok[1])
p2 = getflag(tok[2])
p3 = getflag(tok[3])
n = 0
else:
name = "__TOK_ERROR__"
p1 = "__TOK_ERROR__"
p2 = "__TOK_ERROR__"
p3 = "__TOK_ERROR__"
assert(len(tok) == 2)
n = tok[1]
ls.write("{}{}\n".format(deprecated, name))
ls.write("{}{}\n".format(deprecated, tok[0]))
hd.write("#ifdef _NEED_ARCH_I\n")
hd.write('{{ "{}{}", "{}{}", {}, {}, {}, i_{} }},\n'\
.format(deprecated, tok[0], deprecated, name, p1, p2, p3, tok[0]))
hd.write('{{ "{}{}", {}, i_{} }},\n'\
.format(deprecated, tok[0], n, tok[0]))
hd.write("#else\n")
hd.write("#define I_{} {}\n".format(name.upper(), count))
hd.write("#define I_{} {}\n".format(tok[0].upper(), count))
hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n"
.format(tok[0]))
hd.write("#endif\n\n")

View File

@ -9,6 +9,15 @@
uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \
#define XSRCP(v, p, x) \
if (ACC_FMT_IS_MEM(p->type)) \
v = readmem##x(ctx, p->addr, p->mlen); \
else v = p->val; \
#define SRCP(p) \
if (__builtin_expect(ACC_FMT_IS_MEM(p->type), 0)) \
p->val = readmemsx(ctx, p->addr, p->mlen); \
//----------------------------------------------------------------------------//
#define INTO() \

View File

@ -17,14 +17,10 @@ IMPL_START(loop) {
IMPL_START(b)
{
ulong v;
SRCP(p1);
SRCP(p2);
if (ACC_FMT_IS_MEM(p1->type))
v = readmemsx(ctx, p1->addr, p1->mlen);
else v = p1->val;
COMPARE_SUB(v, p2->val);
COMPARE_SUB(p1->val, p2->val);
if (eval_cond(ctx, ctx->cond))
R(RIP) = p3->val;
@ -34,14 +30,9 @@ IMPL_START(b)
IMPL_START(cmp)
{
ulong v;
SRCP(p1);
if (ACC_FMT_IS_MEM(p1->type))
v = readmemsx(ctx, p1->addr, p1->mlen);
else v = p1->val;
COMPARE_SUB(v, p2->val);
COMPARE_SUB(p1->val, p2->val);
return 0;
}
@ -49,44 +40,20 @@ IMPL_START(cmp)
//----------------------------------------------------------------------------//
IMPL_START(lea) { *r1 = p2->addr; return 1; }
IMPL_START(mov) { XSRCP(*r1, p2, sx); return 1; }
IMPL_START(movzx) { XSRCP(*r1, p2, zx); return 1; }
IMPL_START(mov)
{
if (ACC_FMT_IS_MEM(p2->type))
*r1 = readmemsx(ctx, p2->addr, p2->mlen);
else *r1 = p2->val;
return 1;
}
IMPL_START(movzx)
{
if (ACC_FMT_IS_MEM(p2->type))
{
if (__builtin_expect(p2->mlen == 8, 0))
_except(ctx, E_ILL, "MOVZX with qword memory source");
*r1 = readmemzx(ctx, p2->addr, p2->mlen);
}
else *r1 = p2->val;
return 1;
}
IMPL_START(movsxb) { *r1 = (ulong)(long)(char)(p2->val & 0xFF); return 1; }
IMPL_START(movsxw) { *r1 = (ulong)(long)(short)(p2->val & 0xFFFF); return 1; }
IMPL_START(movsxd) { *r1 = (ulong)(long)(int)(p2->val & 0xFFFFFFFF); return 1; }
IMPL_START(movsxb) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; }
IMPL_START(movsxw) { SRCP(p2); *r1 = (ulong)(long)(short)p2->val; return 1; }
IMPL_START(movsxd) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; }
IMPL_START(xchg)
{
SRCP(p1);
SRCP(p2);
*r2 = p1->val;
if (ACC_FMT_IS_MEM(p2->type))
*r1 = readmemsx(ctx, p2->addr, p2->mlen);
else *r1 = p2->val;
*r1 = p2->val;
return 2;
}
@ -99,15 +66,10 @@ IMPL_START(xchg)
IMPL_START(push)
{
ulong v;
if (ACC_FMT_IS_MEM(p1->type))
v = readmemzx(ctx, p1->addr, p1->mlen);
else v = p1->val;
XSRCP(p1->val, p1, zx);
R(RSP) -= 8;
writemem(ctx, v, R(RSP), 8);
writemem(ctx, p1->val, R(RSP), 8);
return 0;
}
@ -122,17 +84,41 @@ IMPL_START(pop)
IMPL_START(call)
{
SRCP(p1);
R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8);
R(RIP) = p1->val;
if (p2)
{
R(AX0) = p2->val;
return 0;
}
if (p3)
R(AX1) = p3->val;
}
IMPL_START(xcall2)
{
SRCP(p1);
SRCP(p2);
R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8);
R(RIP) = p1->val;
R(AX0) = p2->val;
return 0;
}
IMPL_START(xcall3)
{
SRCP(p1);
SRCP(p2);
SRCP(p3);
R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8);
R(RIP) = p1->val;
R(AX0) = p2->val;
R(AX1) = p3->val;
return 0;
}

View File

@ -81,6 +81,8 @@ IMPL_START(cls)
IMPL_START(bswap)
{
SRCP(p2);
ulong v = p2->val;
*r1 = ((v & 0xFF00000000000000) >> 56)
@ -97,6 +99,8 @@ IMPL_START(bswap)
IMPL_START(wswap)
{
SRCP(p2);
ulong v = p2->val;
*r1 = ((v & 0xFFFF000000000000) >> 48)
@ -109,6 +113,8 @@ IMPL_START(wswap)
IMPL_START(dswap)
{
SRCP(p2);
*r1 = ((p2->val & 0xFFFFFFFF00000000) >> 32)
| ((p2->val & 0x00000000FFFFFFFF) << 32);
@ -121,6 +127,8 @@ IMPL_START(dswap)
IMPL_START(prn)
{
SRCP(p1);
ulong v = p1->val;
// Magic value? :)
@ -135,6 +143,9 @@ IMPL_START(prn)
IMPL_START(prns)
{
if (p1->type != A_REG)
_except(ctx, E_ILL, "PRNS given a non-REG operand");
uchar ch = readmemzx(ctx, R(p1->reg), 1);
COMPARE_SUB(ch, 0);

View File

@ -13,6 +13,9 @@
static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
if (p1->type != A_REG)
_except(ctx, E_ILL, "STOSX given a non-REG operand");
writemem(ctx, p2->val, R(p1->reg), len);
STR_MOVE(p1->reg, len);
}
@ -26,6 +29,9 @@ IMPL_START(stosq) { stos_impl(ctx, p1, p2, 8); return 0; }
static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
if (p1->type != A_REG)
_except(ctx, E_ILL, "SCASX given a non-REG operand");
ulong x = readmemsx(ctx, R(p1->reg), len);
COMPARE_SUB(x, p2->val);

View File

@ -3,18 +3,23 @@
#include <pc/console.h>
// FIXME XXX
//#define _LARGE_SCREEN
#ifndef _LARGE_SCREEN
# define CONSOLE_WIDTH 80
# define CONSOLE_HEIGHT 25
# define CONSOLE_FONT_SIZE 16
# define _MULT 1
#else
# define CONSOLE_WIDTH 160
# define CONSOLE_HEIGHT 50
# define CONSOLE_FONT_SIZE 32
# define _MULT 2
#endif
#define SCREEN_WIDTH (9 * CONSOLE_WIDTH)
#define SCREEN_HEIGHT (16 * CONSOLE_HEIGHT)
#define CONSOLE_WIDTH (80)
#define CONSOLE_HEIGHT (25)
#define CONSOLE_FONT_SIZE (16 * _MULT)
#define SCREEN_WIDTH (9 * CONSOLE_WIDTH * _MULT)
#define SCREEN_HEIGHT (16 * CONSOLE_HEIGHT * _MULT)
#define _SURF_H CONSOLE_FONT_SIZE
SDL_Window *scr_win = NULL;
SDL_Renderer *scr_rend = NULL;
@ -281,7 +286,7 @@ void console_putc(ctx_t *ctx, char ch)
for (y = 0; y < CONSOLE_HEIGHT-1; y++)
if (scr_rects[y] != NULL)
{
scr_rects[y]->y -= 16; // surf->h
scr_rects[y]->y -= _SURF_H; // surf->h
}
console_render(ctx);

View File

@ -62,34 +62,31 @@ static void checkreg(ctx_t *ctx, uint reg)
//
// Verify that given access length is that of a byte/word/dword/qword
//
static void checklength(ctx_t *ctx, uint len)
static void checklength(ctx_t *ctx, instr_t *in, uint len)
{
static const int lentab[9] = { 0, 1, 1, 0, 1, 0, 0, 0, 1 };
if (len > 8 || lentab[len] == 0)
_except(ctx, E_ILL, "Invalid memory access length: %u", len);
_except(ctx, E_ILL, "%s: Invalid memory access length: %u",
in->name, len);
}
//
// Extracts one operand
//
static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
static void extract_param(ctx_t *ctx, instr_t *in, acc_t *p)
{
// Get next operand ModRM-like byte
uchar fmt = fetchb(ctx);
ulong hi = (fmt & 0b11100000) >> 5;
ulong lo = fmt & 0b00011111;
uchar hi = (fmt & 0b11100000) >> 5;
uchar lo = fmt & 0b00011111;
//
// Registers
//
if (hi == 0)
{
if (prm != P_REG)
_except(ctx, E_ILL, "Not expecting a register: %s",
ctx->cur_in->full);
p->reg = lo;
p->type = A_REG;
checkreg(ctx, p->reg);
@ -104,10 +101,6 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
//
if (hi == 7)
{
if (prm != P_IMM)
_except(ctx, E_ILL, "Not expecting an immediate: %s",
ctx->cur_in->full);
switch (lo)
{
case 1:
@ -131,7 +124,8 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
break;
default:
_except(ctx, E_ILL, "Invalid immediate length: %hhu", lo);
_except(ctx, E_ILL, "%s: Invalid immediate length: %hhu",
in->name, lo);
}
return;
@ -141,11 +135,7 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
// Memory operands
//
if (prm != P_MEM)
_except(ctx, E_ILL, "Not expecting a memory access: %s",
ctx->cur_in->full);
checklength(ctx, lo);
checklength(ctx, in, lo);
p->mlen = lo;
switch (hi)
@ -234,31 +224,31 @@ void decode(ctx_t *ctx)
ctx->cond = b2 & SUFF_COND;
// Operand 1?
if (in->prm1 == NOPRM)
if (in->nprms == 0)
{
exec_instr(ctx, in, NULL, NULL, NULL, lock, rep);
return;
}
extract_param(ctx, in->prm1, &p1);
extract_param(ctx, in, &p1);
// Operand 2?
if (in->prm2 == NOPRM)
if (in->nprms == 1)
{
exec_instr(ctx, in, &p1, NULL, NULL, lock, rep);
return;
}
extract_param(ctx, in->prm2, &p2);
extract_param(ctx, in, &p2);
// Operand 1?
if (in->prm3 == NOPRM)
if (in->nprms == 2)
{
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep);
return;
}
extract_param(ctx, in->prm3, &p3);
extract_param(ctx, in, &p3);
exec_instr(ctx, in, &p1, &p2, &p3, lock, rep);
}

View File

@ -66,12 +66,7 @@ enum { NOPRM, P_REG, P_IMM, P_MEM=4 };
struct instr_t
{
char *name;
char *full;
uint prm1;
uint prm2;
uint prm3;
uint nprms;
uint (*func)(ctx_t *, acc_t *, acc_t *, acc_t *,
ulong *, ulong *, ulong *);
};

View File

@ -41,12 +41,10 @@ bool eval_cond(ctx_t *ctx, uint cond)
#define OUTPUT(p, r) { \
if (p->type == A_REG) \
R(p->reg) = r; \
else if (p1->type == A_IMM64) \
_except(ctx, E_ACC, "Trying to output to an IMM64"); \
else { \
assert(ACC_IS_MEM(p)); \
else if (ACC_IS_MEM(p)) \
writemem(ctx, r, p->addr, p->mlen); \
} }
else _except(ctx, E_ACC, "Trying to output to an IMM"); \
}
//
// Executes an instruction

View File

@ -62,7 +62,7 @@ int main(int argc, char **argv)
main_ctx.r = arch_r;
main_ctx.i = arch_i;
#if 1 && !defined(NDEBUG)
#if 0 && !defined(NDEBUG)
main_ctx.dumpsw = 1;
#endif