: cell+ 8 + ; : syswrite ( u c-addr fd -- n ) 1 syscall3 ; : say ( c-addr u -- ) swap 2 syswrite drop ; : emit ( chr -- ) sp cell+ 1 swap 1 syswrite 2drop ; : cr 10 emit ; : decimal 10 base ! ; : hex 16 base ! ; : nip swap drop ; : tuck swap over ; hex : ret, c3 c, ; decimal : cells 8 * ; : allot here @ swap here +! ; : [compile] parse find drop >cfa compile, ; immediate : ' parse find drop >cfa [compile] lit ; immediate \ note: no error handling (yet) : recurse latest @ >cfa compile, ; immediate : literal [compile] lit ; immediate : constant create [compile] lit ret, ; : variable 1 cells allot create [compile] lit ret, ; \ https://wiki.osdev.org/X86-64_Instruction_Encoding \ see dusk os asm/x86.fs \ my idea is that operands are given in the reverse order that \ they are in intel notation, so that intel notation can be vaguely \ turned into this assembler by moving the mnemonic to the end, \ like: mov r11, r12 -> smth like r11 r12 mov, \ a lot of this would probably be more elegant but i have to get around \ to . i don't want to have to hex variable rex variable modrm : asm$ 0 rex ! c0 modrm ! ; : rex.w rex @ 48 or rex ! ; : rex.r rex @ 44 or rex ! ; : rex.x rex @ 42 or rex ! ; : rex.b rex @ 41 or rex ! ; : ax 0 ; : cx 1 ; : dx 2 ; : bx 3 ; : sp 4 ; : bp 5 ; : si 6 ; : di 7 ; \ at least for now, you have to differentiate these from above \ by manually setting rex. : r8 0 ; : r9 1 ; : r10 2 ; : r11 3 ; : r12 4 ; : r13 5 ; : r14 6 ; : r15 7 ; \ are there instructions that use registers but Not r/m bytes? \ i don't actually know \ example idea: (from execute below) \ rex.w rex.r r11 rex.b r14 0 d) mov, \ rex.w rex.r r14 rex.b r14 8 d) lea, \ rex.b r11 call, decimal : execute [ hex 4d c, 8b c, 1e c, \ mov r11, [r14] \ REX.W + 8B /r -- MOV r64, r/m64 \ rex w (64 bit operand size), r (modrm.reg ext), b (modrm.rm ext) \ modrm 00 011 110 \ mod [r/m] reg 1.011 (r11) r/m 1.110 (r14) 4d c, 8d c, 76 c, 08 c, \ lea r14, [r14+8] \ REX.W + 8D /r -- LEA r64, m \ rex w (64 bit operand size), r (modrm.reg ext), b (modrm.rm ext) \ modrm 01 110 110 \ mod [r/m+disp8] reg 1.110 (r14) r/m 1.110 (r14) 41 c, ff c, d3 c, \ call r11 \ FF /2 -- CALL r/m64 \ rex b (.rm ext) \ modrm 11 010 011 \ mod r/m reg /2 r/m 1.011 (r11) decimal ] ; \ TODO interpret mode strings? : s" [ char " ] literal 1 >in +! ( skip spc ) [compile] litstring ; immediate : ." [compile] s" ' say compile, ; immediate \ lol this word breaks the highlighting, here have another " \ jump helpers from forth83 (got them from pforth tho ehehe) \ < backward jump > forward jump \ adding/subtracting 4 gets to the next instruction. : mark here @ 0 d, ; : >resolve dup here @ swap - 4 - swap d! ; : begin mark ; immediate ( I: -- a ) : else branch >mark swap >resolve ; immediate : then >resolve ; immediate : while 0branch >mark ; immediate : repeat branch swap resolve ; immediate : / /mod swap drop ; : mod /mod drop ; : negate 0 swap - ; : abs dup 0< if negate then ; 32 constant bl : space bl emit ; : spaces begin dup 0> while space 1- repeat drop ; \ PNO \ mostly from pforth 255 allot variable pad drop variable hld : <# pad hld ! ; : hold 1 hld -! ( chr ) hld @ c! ; : sign 0< if [ char - ] literal hold then ; : # base @ /mod swap 9 over > if 7 + then [ char 0 ] literal + hold ; : #s begin # dup 0= until ; : #> drop hld @ pad over - ; : (u.) <# #s #> ; : u. (u.) say space ; : u.r >r (u.) r> over - spaces say ; : (.) dup abs <# #s swap sign #> ; : . (.) say space ; : .r >r (.) r> over - spaces say ; : (.byte) hex <# # # #> decimal ; : .byte (.byte) say space ; : (.word) hex <# # # # # #> decimal ; : .word (.word) say space ; : (.dword) hex <# # # # # # # # # #> decimal ; : .dword (.dword) say space ; : (.qword) hex <# # # # # # # # # # # # # # # # # #> decimal ; : .qword (.qword) say space ; : ? @ . ; : .s sp 8 + ( skip sp itself ) begin dup s0 @ >= while dup @ .qword 8 + repeat drop cr ; bye