
2019å¹Žãæ¥ãŠã幎æ«å¹Žå§ã¯çµããã«è¿ã¥ããŠããŸãã ãã€ããã³ãã³ãã倿°ãã«ãŒããæãåºãå§ããŸããã...
ãããã®ç¥æ¥ã§ãã§ã«å¿ããŠãããã®ã äžç·ã«èŠããŠããå¿
èŠããããŸãïŒ
仿¥ã¯ããã€ããã·ã³çšã®ã€ã³ã¿ãŒããªã¿ãŒãäœæããŸãã ããã¯3çªç®ã®èšäºã§ãæåã®ããŒãã¯
ããŒã1 ã
ããŒã2ã§ãã
ã¿ãªãããæããŸããŠããã§ãšããç«ãžããããïŒ
ãŸãã
fpaukããã®è³ªåã«çããŸãã ãããã®è³ªåã¯ééããªãæ£ããã§ãã çŸåšããã®ãã€ããã·ã³ã®ã¢ãŒããã¯ãã£ã¯ããã€ã¬ã¯ãããã»ããµã¢ãã¬ã¹ã§åäœããããã«ãªã£ãŠããŸãã ãããããããã®ã¢ãã¬ã¹ã¯ãã€ãã³ãŒãã§ã¯ãªããã·ã¹ãã ã®èµ·ååŸã«åœ¢æãããŸãã ã·ã¹ãã ã®èµ·ååŸãä»»æã®ãã€ã³ã¿ãŒãäœæã§ãããã®ã³ãŒãã¯ã©ã®ãã©ãããã©ãŒã ã§ãæ£åžžã«æ©èœããŸãã ããšãã°ã倿°ãŸãã¯é
åã®ã¢ãã¬ã¹ã¯ãvar0ã³ãã³ãã§ååŸã§ããŸãã ãã®ã³ãã³ãã¯ã©ã®ãã©ãããã©ãŒã ã§ãæ©èœãããã®ãã©ãããã©ãŒã åºæã®æ£ããã¢ãã¬ã¹ãè¿ããŸãã ãã®åŸããã®ã¢ãã¬ã¹ãèªç±ã«æäœã§ããŸãã
ããã§ãã
fpaukã¯æ£ããã ã¢ãã¬ã¹ããã€ãã³ãŒãã«ä¿åããããšã¯ã§ããŸããã ãã©ãããã©ãŒã ã«äŸåããªãã³ãŒããäœæã§ããããšãããããŸãããããã®ããã«ã¯ããã€ãã®åªåãå¿
èŠã§ãã ç¹ã«ãã¢ãã¬ã¹ããã€ãã³ãŒãã«å«ãŸããŠããªãããšã確èªããŠãã ããã ãŸããããšãã°ãã³ã³ãã€ã«ãããã³ãŒãããã¡ã€ã«ã«ä¿åãããšãããããååŸã§ããŸãã ããã«ã¯ããŒã¿ãå«ãŸããã¢ãã¬ã¹ã«ããããšãã§ããŸãã ããšãã°ãããã®å€æ°ãã³ã³ããã¹ããªã©ã®å€ã
ãã®ãããªåé¡ãåãé€ãã«ã¯ãã¢ãã¬ã¹ãä»®æ³åããå¿
èŠããããŸãã x86ããã»ããµã®ã¢ãã¬ã¹æå®ã¯éåžžã«åŒ·åã§ãããã»ãšãã©ã®å Žåã远å ã®ã³ãã³ãã远å ãããŸããã ããã§ãã絶察ã¢ãã¬ã¹ã䜿çšããŠãçŸåšã®ã¢ãŒããã¯ãã£ãç¶ç¶ããŸãã ãããŠããã¹ããéå§ãããšãã¢ãã¬ã¹ãä»®æ³ã¢ãã¬ã¹ã«åå®è¡ããŠããããããã©ãŒãã³ã¹ã«ã©ã®ããã«åœ±é¿ãããã確èªã§ããŸãã ããã¯é¢çœãã§ãã
ãŠã©ãŒã ã¢ãã
ãããŠä»ãå°ããã¬ãŒãã³ã°ã å°ãããŠã䟿å©ãªãã€ãã³ãã³ãã®ãããããã1ã€äœæããŸãããã ãããã¯ãã³ãã³ãnipãemitã1 +ã+ïŒã-ïŒãcountããªã¿ãŒã³ã¹ã¿ãã¯r>ã> rãr @ãæååãªãã©ã«ïŒ "ïŒãããã³å®æ°ã¯ãŒã1ã2ã3ã4ã 8.ã³ãã³ãã®è¡šã«ããããå«ããããšãå¿ããªãã§ãã ããã
ãããã®ã³ãã³ãã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãb_nip = 0x39 bcmd_nip: pop rax mov [rsp], rax jmp _next b_emit = 0x81 bcmd_emit: pop rax mov rsi, offset emit_buf # mov [rsi], al mov rax, 1 # â 1 - sys_write mov rdi, 1 # â 1 - stdout mov rdx, 1 # push r8 syscall # pop r8 jmp _next b_wp = 0x18 bcmd_wp: incq [rsp] jmp _next b_setp = 0x48 bcmd_setp: pop rcx pop rax add [rcx], rax jmp _next b_setm = 0x49 bcmd_setm: pop rcx pop rax sub [rcx], rax jmp _next b_2r = 0x60 bcmd_2r: pop rax sub rbp, 8 mov [rbp], rax jmp _next b_r2 = 0x61 bcmd_r2: push [rbp] add rbp, 8 jmp _next b_rget = 0x62 bcmd_rget: push [rbp] jmp _next b_str = 0x82 bcmd_str: movzx rax, byte ptr [r8] lea r8, [r8 + rax + 1] jmp _next b_count = 0x84 bcmd_count: pop rcx movzx rax, byte ptr [rcx] inc rcx push rcx push rax jmp _next b_num1 = 0x03 bcmd_num1: push 1 jmp _next b_num2 = 0x04 bcmd_num2: push 2 jmp _next b_num3 = 0x05 bcmd_num3: push 3 jmp _next b_num4 = 0x06 bcmd_num4: push 4 jmp _next b_num8 = 0x07 bcmd_num8: push 8 jmp _next
nipã³ãã³ãã¯ãã¹ã¿ãã¯ã®æäžéšã®äžã«ããåèªãåé€ããŸãã ããã¯ãã¹ã¯ããããããã³ãã³ããšåçã§ãã ããã¯åœ¹ç«ã€å ŽåããããŸãã
emitã³ãã³ãã¯ãã¹ã¿ãã¯ãã1æåãããã·ã¥ããŸãã åãã·ã¹ãã ã³ãŒã«çªå·1ã䜿çšããæåã¯é·ã1ã®ãããã¡ã«é
眮ãããŸãã
countã³ãã³ãã¯éåžžã«åçŽã§ã-ã¹ã¿ãã¯ããã«ãŠã³ã¿ãŒã®ããè¡ã®ã¢ãã¬ã¹ãååŸãã2ã€ã®å€ã«å€æããŸã-ã«ãŠã³ã¿ãŒã®ãªãè¡ã®ã¢ãã¬ã¹ãšé·ãã
b_2rãb_r2ãb_rgetã³ãã³ãã¯ããã©ãŒãã¯ãŒãr>ã> rãr @ã§ãã æåã®é¢æ°ã¯æ»ãã¹ã¿ãã¯ããåèªãååŸããç®è¡ã¹ã¿ãã¯ã«é
眮ããŸãã 2çªç®ã¯åå¯Ÿã®æäœãå®è¡ããŸãã 3çªç®ã®ãã®ã¯æ»ãã¹ã¿ãã¯ããåèªãã³ããŒããç®è¡1ã«å
¥ããŸããæ»ãã¹ã¿ãã¯ã¯å€æŽãããŸããã
b_setpããã³b_setmã³ãã³ãã¯+ïŒãšããåèªã§ãã ããã³-ïŒ..ã¹ã¿ãã¯ããå€ãšã¢ãã¬ã¹ãååŸããæå®ãããã¢ãã¬ã¹ã®ã¯ãŒãã倿ŽããŠãã¹ã¿ãã¯ã«å€ã远å ãŸãã¯åé€ããŸãã
b_strã³ãã³ãã«ã¯ãä»»æã®é·ãã®ãã©ã¡ãŒã¿ãŒïŒã«ãŠã³ã¿ãŒä»ãã®è¡ïŒããããŸãã ãã®è¡ã¯ã³ãã³ããã€ãã®åŸã®ãã€ãã³ãŒãã«ãããã³ãã³ãã¯ãã®è¡ã®ã¢ãã¬ã¹ãã¹ã¿ãã¯ã«ããã·ã¥ããŸãã å®éãããã¯æååãªãã©ã«ã§ãã
ããŒã ã®ä»ã®ã¡ã³ããŒã¯ã³ã¡ã³ããå¿
èŠãšããªããšæããŸãã
ãŸãã宿°æååïŒã "ïŒãåºåããã³ãã³ããäœæããŸããæ¬¡ã®ããã«ãå
¥åãããšã³ããªãã€ã³ããšããŠå®è£
ããŸãã
b_strp = 0x83 bcmd_strp: movsx rax, byte ptr [r8] inc r8 push rax push r8 add r8, rax b_type = 0x80 bcmd_type: mov rax, 1 # â 1 - sys_write mov rdi, 1 # â 1 - stdout pop rdx # pop rsi # push r8 syscall # pop r8 jmp _next
ãã®ã³ãã³ãã¯ãb_strãšåæ§ã«æ§æãããŠããŸãã 圌女ã ããã¹ã¿ãã¯ã«äœã眮ããŸããã ãã©ã¡ãŒã¿ãšããŠãã®ã³ãã³ãã®åŸãã«ããè¡ã¯ãåã«ãŠãŒã¶ãŒã«è¡šç€ºãããŸãã
ãŠã©ãŒã ã¢ããã¯çµäºããŸããããã£ãšæ·±å»ãªãã®ã®æãæ¥ãŸããã ã¯ãŒããžã§ãã¬ãŒã¿ãŒãšä»ã®varã³ãã³ããæ±ããŸãããã
ã¯ãŒããžã§ãã¬ãŒã¿ãŒ
倿°ãæãåºããŠãã ããã æ¢ç¥ã®ãã€ãã³ãŒãã¬ãã«ã§ã®é
åã®é
眮ïŒvar0ã³ãã³ãïŒã æ°ãã倿°ãäœæããããã«ããã©ãŒãã¯æ¬¡ã®æ§æã䜿çšããŸãã
variable < >
ãã®ã·ãŒã±ã³ã¹ãå®è¡ãããšãæ°ããåèª<倿°å>ãäœæãããŸãã ãã®æ°ããã¯ãŒãã®å®è¡ã«ãããã¹ã¿ãã¯äžã®ã¢ãã¬ã¹ãããã·ã¥ããã倿°ã®å€ãä¿åãããŸãã ãã©ãŒãã«ã¯å®æ°ããããæ¬¡ã®ããã«äœæãããŸãã
<> constant < >
宿°ãäœæããåŸãåèª<宿°å>ãå®è¡ãããšãã¹ã¿ãã¯<å€>ã«é
眮ãããŸãã
ãããã£ãŠãåèªå€æ°ãšåèªå®æ°ã¯ã©ã¡ããçæèªã§ãã æ°ããåèªãäœæããããã«èšèšãããŠããŸãã èŠå¡ã§ã¯ããã®ãããªåèªã¯create ... does>æ§é ã䜿çšããŠèšè¿°ãããŸãã
倿°ãšå®æ°ã¯æ¬¡ã®ããã«å®çŸ©ã§ããŸãã
: variable create 0 , does> ; : constant create , does> @ ;
ããã¯ã©ãããæå³ã§ããïŒ
åèªcreateã¯ãå®è¡ããããšãå
¥åã¹ããªãŒã ããå®è¡ããããšãã«ååŸããååã§æ°ããåèªãäœæããŸãã äœæåŸãåèªãå®è¡ããåã«åèªã®ã·ãŒã±ã³ã¹ãå®è¡ãããŸã>ã ãããããã®åèªã®å®è¡ã®ç¬éã«ãdoes>ã®åŸã«æžãããŠããããšãå®è¡ãããŸãã åæã«ãããŒã¿ã¢ãã¬ã¹ã¯æ¢ã«ã¹ã¿ãã¯äžã«ãããŸãïŒãã©ãŒãã®ãããŒã¿ãã£ãŒã«ããã§èšãããã«ïŒã
ãããã£ãŠã倿°ãäœæãããšãã·ãŒã±ã³ã¹ã0ããå®è¡ãããŸããããã¯ããŒãå
å¡«ã®ãã·ã³ã¯ãŒãã®äºçŽã§ãã ãããŠãäœæãããåèªãå®è¡ããããšããäœãè¡ãããŸããïŒåŸã¯äœããããŸããïŒã å€ãæ ŒçŽãããã¡ã¢ãªã¢ãã¬ã¹ã¯ãåã«ã¹ã¿ãã¯ã«æ®ããŸãã
宿°ã®å®çŸ©ã§ã¯ãåèªã¯ã¹ã¿ãã¯äžã«ããå€ãåããŠäºçŽãããŠããŸãã äœæãããåèªãå®è¡ããããšãã@ããå®è¡ãããæå®ãããã¢ãã¬ã¹ã®å€ãååŸãããŸãã
次ã«ãäœæããåèªãã©ã®ããã«é
眮ã§ããããèããŠã¿ãŸãããã ããŒã¿ã¢ãã¬ã¹ãã¹ã¿ãã¯ïŒvar0ãªã©ïŒã«ããã·ã¥ããç¹å®ã®ã¢ãã¬ã¹ã§ãããã€ãã³ãŒãã«å¶åŸ¡ãç§»ããŸãã var0ã³ãã³ãã¯ããã«æ»ããŸãã ãããããã®å Žåããªã¿ãŒã³ã§ã¯ãªããå®éã«ç§»è¡ãè¡ãå¿
èŠããããŸãã
ããäžåºŠãäœãããå¿
èŠãããããå®åŒåããŸãã
- ã¹ã¿ãã¯ã«ããŒã¿ã¢ãã¬ã¹ã眮ã
- ã®åŸã«ã³ãŒãã«ãžã£ã³ããã>
å¶åŸ¡ãå¥ã®ãã€ãã³ãŒãã¢ãã¬ã¹ã«è»¢éããã ãã§ãæåã«æ¬¡ã®ãã€ãïŒR8ïŒã®ã¢ãã¬ã¹ãã¹ã¿ãã¯ã«é
眮ããå¿
èŠãããããšãããããŸãã
ããã¯ã»ãšãã©åå²ã³ãã³ãã§ãïŒ ãããŠãããã§åœŒå¥³ã¯äžäººã§ã¯ãããŸããã ãã§ã«branch8ãšbranch16ããããŸãã æ°ããvar8ããã³var16ã³ãã³ãã«ååãä»ããããããåå²ã³ãã³ããžã®åãªããšã³ããªãã€ã³ãã«ããŸãã ç§»è¡ããŒã ãžã®ç§»è¡ãä¿åããŸã:)ãããã£ãŠã次ã®ããã«ãªããŸãã
b_var8 = 0x29 bcmd_var8: push r8 b_branch8 = 0x10 bcmd_branch8: movsx rax, byte ptr [r8] add r8, rax jmp _next b_var16 = 0x30 bcmd_var16: push r8 b_branch16 = 0x11 bcmd_branch16: movsx rax, word ptr [r8] add r8, rax jmp _next
è¯ãæ¹æ³ã§ã¯ãvar32ã³ãã³ããåäœããvar64ãåäœããŸãã éåžžã®é·ç§»ã¯ããã»ã©é·ããªãããããã®ãããªé·ãé·ç§»ã¯ãããŸããã ããããvarã³ãã³ãã®å Žåãããã¯éåžžã«çŸå®çãªã±ãŒã¹ã§ãã ããããä»ã®ãšããããããã®ã³ãã³ãã¯å®è¡ããŸããã å¿
èŠã«å¿ããŠãåŸã§è¡ããŸãã
åèªãžã§ãã¬ãŒã¿ãŒãæŽçãããŠããŸãã èŸæžã決ããçªã§ããã
èªåœ
éåžžããã©ãŒããã£ã¯ã·ã§ããªãŒã«ã€ããŠåçŽã«è©±ããšããã£ã¯ã·ã§ããªãšã³ããªã®åæ¹åãªã¹ãã®åœ¢åŒã§è¡šç€ºãããŸãã å®éãç Šã¯å€ãã®èŸæžããµããŒãããŠããããããã¹ãŠãå°ãè€éã§ãã å®éããããã¯æšã§ãã ãã®ãããªããªãŒå
ã®åèªã®æ€çŽ¢ã¯ãã·ãŒããã§å§ãŸããŸããããã¯çŸåšã®èŸæžã®æåŸã®åèªã§ãã çŸåšã®èŸæžã¯ã³ã³ããã¹ã倿°ã«ãã£ãŠå®çŸ©ãããæåŸã®åèªã®ã¢ãã¬ã¹ã¯èŸæžã®åèªã«ãããŸãã å¥ã®å€æ°ã¯èŸæžã管çããããã«äœ¿çšãããŸã-ããã¯æ°ããåèªã远å ãããèŸæžãå®çŸ©ããŸãã ãããã£ãŠã1ã€ã®èŸæžãæ€çŽ¢çšã«ã€ã³ã¹ããŒã«ããå¥ã®èŸæžã«æ°ããåèªãå«ããããšãã§ããŸãã
åçŽãªå Žåãå€ãã®èŸæžã®ãµããŒããè¡ããªãããšãå¯èœã§ãããç§ã¯äœãåçŽåããªãããšã«ããŸããã å®éããã€ãã³ãŒãããã€ããã·ã³ãçè§£ããããã«ããã®ã»ã¯ã·ã§ã³ã§èª¬æãããŠããããšãç¥ãå¿
èŠã¯ãããŸããã ãããã£ãŠãèå³ã®ãªã人ã¯ããã®ã»ã¯ã·ã§ã³ãã¹ãããã§ããŸãã ããŠã誰ã詳现ãç¥ãããã§ãã-ã©ããïŒ
æåã¯ãforthãšããååã®åºæ¬çãªèŸæžããããŸãã ããã¯ããã®ãããªèšèãããããšãæå³ããŸãã ãã®åèªã¯ãèŸæžããšãåŒã°ããå€å°ã®æ··ä¹±ããããŸãã ãããã£ãŠãåèªã«é¢ããŠã¯ãèŸæžã®åèªãšåŒã³ãŸãã
ãã®èŸæžã䜿çšããŠæ°ããèŸæžãäœæãããŸãã
vocabulary < >
ããã«ããã<created dictionary name>ãšããååã®åèªãäœæãããŸãã å®è¡ããããšããã®åèªã¯äœæãããèŸæžãæ€çŽ¢ã®éå§èŸæžãšããŠèšå®ããŸãã
å®éãèŸæžã®åèªã«ã¯ããã®èŸæžã®æåŸã®èšäºãžã®ãªã³ã¯ããããããããæ€çŽ¢ãéå§ãããŸãã ãããŠå®è¡æã«ããã®èŸæžã®åèªã¯ã³ã³ããã¹ã倿°ã®ããŒã¿ãã£ãŒã«ããžã®ãªã³ã¯ãæžã蟌ã¿ãŸãã
åŸã§ãèªåœãäœæããããšãå¯èœã«ãªããŸããèªåœã¯ãçŸåšã®å®è£
ã§ã¯èŠå¡ã§éåžžã«ç°¡åã«èª¬æãããŠããŸãã
: vocabulary create context @ , does> context ! ;
ã ãããèšèãåã«äœæããŸãã var8ã³ãã³ãã䜿çšããŸãã ãã³ã³ããã¹ãïŒããã€ãã³ãŒãã¯ãããŒã¿ãã£ãŒã«ãã®çŽåŸã«é
眮ãããŸãã
forth: .byte b_var8 .byte does_voc - . - 1 .quad 0 # <-- . , - . does_voc: .byte b_call8 .byte context - . - 1 .byte b_set .byte b_exit
ããã§ãèŸæžèªäœã®äœæã«æ»ããŸãã
äžè¬ã«ãç Šã§ã¯ãã¡ã¢ãªå
ã®åèªã®èª¬æã¯ãèŸæžãšã³ããªããšåŒã°ããŸãã éåžžã®çšèªã§ã¯ãèšäºã®ã¿ã€ãã«ãšãã®ã³ãŒãããããŸãã ããããç Šã§ã¯ãã¹ãŠãããŸãäžè¬çã§ã¯ãªãããååãã£ãŒã«ããããéä¿¡ãã£ãŒã«ããããã³ãŒããã£ãŒã«ããããããŒã¿ãã£ãŒã«ãããšåŒã°ããŸãã ãããåŸæ¥ã®çšèªã§äœãæå³ããã®ããã話ãããŸãã
ååãã£ãŒã«ãã¯ããã«ãŠã³ã¿ãŒä»ãã®è¡ããšããåèªã®ååã§ãã å€ããã¹ã«ã«ã®ããã§ã-æååã®é·ãã®ãã€ããæ¬¡ã«æååã ãªã³ã¯ãã£ãŒã«ãã¯ãåã®èšäºãžã®ãªã³ã¯ã§ãã 以åã¯åãªãã¢ãã¬ã¹ã§ãããããã©ãããã©ãŒã ã«äŸåããªãã³ãŒãããããããã¯ãªãã»ããã«ãªããŸãã åŸæ¥ã¯ç Šã«ãã£ãã³ãŒããã£ãŒã«ãã¯ããã·ã³ã³ãŒãïŒå®è£
ãçŽæ¥ã·ã£ã€ãªå ŽåïŒã§ãããã«ãŒãã«å€ã®åèªã«å¯ŸããŠã¯_callãåŒã³åºãããŠããŸããã ãã€ãã³ãŒãããããŸãã ãŸããããŒã¿ãã£ãŒã«ãã¯ãããŒã¿ãå«ãåèªçšã§ããããšãã°ã倿°ã宿°çšã§ãã ã¡ãªã¿ã«ãåèªèŸæžããããæããŸãã
ã³ã³ãã€ã©ã«ã¯ããŸã ãã©ã°ãå¿
èŠã§ãã éåžžãç Šã«ã¯ãã 1ã€ã®ãã©ã°ãå¿
èŠã§ã-峿ã§ãé·ããã€ãã«é
眮ãããŸãïŒå¥ã®ãã©ã°ãããå ŽåããããŸã-é衚瀺ïŒã ãã ããããã¯ã³ãŒããã£ãŒã«ãã«åŒã³åºããããšãã«ããã»ããµå¶åŸ¡ã転éãããçŽæ¥çž«è£œã³ãŒãçšã§ãã ããããç§ãã¡ã«ã¯ç°ãªãèšèããããŸã-ãã€ãã³ãŒããšãã·ã³ã³ãŒãããããŠå°ãªããšã2ã€ãããã«ã¯3ã€ã®ãã©ã°ãå¿
èŠã§ãã
éä¿¡åéã«ã¯ã©ããããå¿
èŠã§ããïŒ æåã¯ã16ãããã䜿çšãããã£ãã ããã¯åã®åèªãžã®ãªã³ã¯ã§ãããåèªã¯ééããªã64 Kbæªæºã§ãã ãããããã®åèªã«ã¯ã»ãšãã©ãã¹ãŠã®ãµã€ãºã®ããŒã¿ââãå«ããããšãã§ããããšãæãåºããŸããã ããã«ãããã€ãã®èŸæžãããå Žåããªã³ã¯ã¯å€ãã®åèªãééã§ããŸãã ã»ãšãã©ã®å Žåã8ãããã§ååã§ããã16ããããš32ãããã§ãããŸããŸããã4GBãè¶
ããããŒã¿ãããå Žåã¯ã64ãããã§ãããããŸãã ããŠããã¹ãŠã®ãªãã·ã§ã³ããµããŒãããŸãããã 䜿çšããããªãã·ã§ã³-ãã©ã°ãèšå®ããŸãã å°ãªããšã4ã€ã®ãã©ã°ã倿ããŸãã峿屿§ãã³ã¢ã¯ãŒã屿§ãããã³äœ¿çšãããéä¿¡ãã£ãŒã«ãã®ããªã¢ã³ãããšã«2ãããã§ãã ä»ã®æ¹æ³ã§ã¯ãªãããã©ã°ã«å¥ã®ãã€ãã䜿çšããå¿
èŠããããŸãã
次ã®ããã«ãã©ã°ãå®çŸ©ããŸãã
f_code = 0x80 f_immediate = 0x60
f_codeãã©ã°ã¯ã¢ã»ã³ãã©ãŒã§èšè¿°ãããã«ãŒãã«ã¯ãŒãçšã§ãããf_immediateãã©ã°ã¯ã³ã³ãã€ã©ãŒã«ãšã£ãŠæçšã§ããããã«ã€ããŠã¯æ¬¡ã®èšäºã§èª¬æããŸãã ãŸãã2ã€ã®æäžäœãããã«ãããéä¿¡ãã£ãŒã«ãã®é·ãïŒ1ã2ã4ããŸãã¯8ãã€ãïŒã決ãŸããŸãã
ãããã£ãŠãèšäºã®ã¿ã€ãã«ã¯æ¬¡ã®ããã«ãªããŸãã
- ãã©ã°ïŒ1ãã€ãïŒ
- éä¿¡ãã£ãŒã«ãïŒ1ã8ãã€ãïŒ
- ååã®é·ããã€ã
- ååïŒ1-255ãã€ãïŒ
ãããŸã§ã¯ãããã¯ããã¢ã»ã³ãã©ãŒã®æ©èœã䜿çšããŠããŸããã ãããŠä»ãããããå¿
èŠã§ãã 以äžã¯ãåèªã®ã¿ã€ãã«ã圢æããããã®ååé
ç®ãæã€ãã®ãããªãã¯ãã§ãã
.macro item name, flags = 0 link = . - p_item 9: .if link >= -256/2 && link < 256/2 .byte \flags .byte link .elseif link >= -256*256/2 && link < 256*256/2 .byte \flags | 1 .word . - p_item .elseif link >= -256*256*256*256/2 && link < 256*256*256*256/2 .byte \flags | 2 .int . - p_item .elseif link >= -256*256*256*256*256*256*256*256/2 && link < 256*256*256*256*256*256*256*256/2 .byte \flags | 3 .quad . - p_item .endif p_item = 9b .byte 9f - . - 1 .ascii "\name" 9: .endm
ãã®ãã¯ãã¯å€p_itemã䜿çšããŸã-ããã¯åã®èŸæžãšã³ããªã®ã¢ãã¬ã¹ã§ãã æåŸã®ãã®å€ã¯ãå°æ¥ã®äœ¿çšã®ããã«æŽæ°ãããŸãïŒp_item = 9bã ããã§9bã¯ã©ãã«ã§ãããæ°åã§ã¯ãªããæ··åããªãã§ãã ãã:)ãã¯ãã«ã¯2ã€ã®ãã©ã¡ãŒã¿ãŒããããŸã-åèªã®ååãšãã©ã°ïŒãªãã·ã§ã³ïŒã ãã¯ãã®éå§æã«ãåã®åèªãžã®ãªãã»ãããèšç®ãããŸãã æ¬¡ã«ããªãã»ããã®ãµã€ãºã«å¿ããŠãç®çã®ãµã€ãºã®ãã©ã°ãšéä¿¡ãã£ãŒã«ããã³ã³ãã€ã«ãããŸãã æ¬¡ã«ãååã®é·ãã®ãã€ããšååèªäœã
次ã®ããã«ãæåã®åèªp_itemã®åã«å®çŸ©ããŸãã
p_item = .
ãããã¯ãã¢ã»ã³ãã©ãŒã®çŸåšã®ã³ã³ãã€ã©ãŒã¢ãã¬ã¹ã§ãã ãã®å®çŸ©ã®çµæãæåã®åèªã¯ããèªäœãæããŸãïŒéä¿¡ãã£ãŒã«ãã¯0ã«ãªããŸãïŒã ããã¯èŸæžã®çµããã®å
åã§ãã
ãšããã§ãã«ãŒãã«ã¯ãŒãã®ã³ãŒããã£ãŒã«ãã«ã¯äœãå
¥ããŸããïŒ å°ãªããšãã©ããã«ã³ãã³ãã³ãŒããä¿åããå¿
èŠããããŸãã ç§ã¯æãåçŽãªéãé²ãããšã«ããŸããã ã«ãŒãã«ã¯ãŒãã«ã¯ããã€ãã³ãŒãããããŸãã ã»ãšãã©ã®ããŒã ã§ã¯ãããã¯åãªããã€ãã³ãã³ãã§ããã®åŸã«b_exitãç¶ããŸãã ãããã£ãŠãã€ã³ã¿ãŒããªã¿ãŒã®å Žåãf_codeãã©ã°ãåæããå¿
èŠã¯ãªãããã®ããã®ã³ãã³ãã¯äœã®éãããããŸããã å
šå¡ã®ãã€ãã³ãŒããåŒã³åºãã ãã§ãã
ãã®ãªãã·ã§ã³ã«ã¯å¥ã®å©ç¹ããããŸãã ãã©ã¡ãŒã¿ãŒä»ãã®ã³ãã³ãã®å Žåãå®å
šãªãã©ã¡ãŒã¿ãŒãæå®ã§ããŸãã ããšãã°ãFortå®è£
ã§çŽæ¥çž«è£œã³ãŒãã䜿çšããŠlitã³ãã³ããåŒã³åºããšãã·ã¹ãã ãã¯ã©ãã·ã¥ããŸãã ãããŠãããã§ã¯ãããšãã°ã0ãç¹ç¯ãããã®ã·ãŒã±ã³ã¹ã¯ãã¹ã¿ãã¯ã«0ã眮ãã ãã§æžã蟌ãŸããŸãã ãã©ã³ãã§ãå®å
šã«è¡ããŸãïŒ
.byte branch8 .byte 0f - . 0: .byte b_exit
ãã®ãããªåŒã³åºãã§ã¯ãªãŒããŒããããçºçããŸãããã€ã³ã¿ãŒããªã¿ãŒã«ãšã£ãŠã¯éèŠã§ã¯ãããŸããã ãããŠãã³ã³ãã€ã©ã¯ãã©ã°ãåæããæ£ç¢ºã§é«éãªã³ãŒããã³ã³ãã€ã«ããŸãã
ãã¡ãããæåã®åèªã¯ãforthããšããåèªã«ãªããŸãããããäœæããåºæ¬çãªèŸæžã§ãã ããã§ã¯ãdos>ã®åŸã«ã³ãŒããžã®ãªã³ã¯ãèšèŒãã䟿å©ãªvarã³ãã³ããå
¥åããŠãã ããã åã®ã»ã¯ã·ã§ã³ã§ãã®ã³ãŒããåŒçšããŸããããèŠåºããä»ããŠç¹°ãè¿ããŸãã
p_item = . item forth .byte b_var8 .byte does_voc - . - 1 .quad 0 does_voc: .byte b_call8 .byte context - . - 1 .byte b_set .byte b_exit
ãããŠãããã«ã³ã³ããã¹ã倿°ãäœæããåèªãæ€çŽ¢ããããã«ããããå¿
èŠãšããŸãã
item .byte b_var0 .quad 0 item context context: .byte b_var0 .quad 0
ãããŠä»ãããªãã¯ææ
¢ããŠãã¢ã»ã³ãã©ãŒã§f_codeãã©ã°ã䜿ã£ãŠæžããååèªã®ã¿ã€ãã«ãæžãå¿
èŠããããŸãïŒ
item 0, f_code .byte b_num0 .byte b_exit item 1, f_code .byte b_num1 .byte b_exit ... item 1-, f_code .byte b_wm .byte b_exit item 1+, f_code .byte b_wp .byte b_exit item +, f_code .byte b_add .byte b_exit item -, f_code .byte b_sub .byte b_exit item *, f_code .byte b_mul .byte b_exit
ãªã©...
ããŒã ããã€ãã³ãŒãã§èšè¿°ããããšãããã«ç°¡åã«ãªããŸãã æ¬¡ã®äŸã®ããã«ããã€ãã³ãŒãã®çŽåã«èŠåºãã远å ããŸãã
item hold hold: .byte b_call8 .byte holdpoint - . - 1 # holdpoint ...
ãã©ã¡ãŒã¿ãŒä»ãã®ã³ãã³ãã®å Žåãå®å
šãªãã©ã¡ãŒã¿ãŒãäœæããŸãã ããšãã°ãLiteã³ãã³ããæ°å€Piãè¿ãããã«ããŸãã誰ããããããã€ã³ã¿ã©ã¯ãã£ãã«åŒã³åºããšããã®ãããªã€ãŒã¹ã¿ãŒããããŸã:)
item lit8, f_code .byte b_lit8 .byte 31 .byte b_exit item lit16, f_code .byte b_lit16 .word 31415 .byte b_exit item lit32, f_code .byte b_lit32 .int 31415926 .byte b_exit item lit64, f_code .byte b_lit64 .quad 31415926535 .byte b_exit
ãªã¹ãã®æåŸã®åèªã¯ãåèªbyeã象城ããŠããŸãã ãã ããããŒã¿ãã£ãŒã«ãã®ãã®ã¯ãŒãã®ã¢ãã¬ã¹ãåæåããå¿
èŠããããŸãã ãã®åèªã®ã¢ãã¬ã¹ãååŸããã«ã¯ãvar0ã³ãã³ãã䜿çšããŸãã
last_item: .byte b_var0 item bye, f_code .byte b_bye
ãã®èšèšã§ã¯ããã€ãã³ãŒãã§ã¢ãã¬ã¹last_itemãåŒã³åºããšãåèªbyeã®ã¢ãã¬ã¹ãååŸããŸãã ã¯ãŒãã®ããŒã¿ãã£ãŒã«ãã«æžã蟌ãã«ã¯ãåã«å®è¡ããç®çã®ã¢ãã¬ã¹ãã³ã³ããã¹ãå
ã«ãããŸãã ãããã£ãŠãã·ã¹ãã åæåã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
forth last_item context @ !
ãããŠãã€ã³ã¿ããªã¿ã«çŽæ¥é²ã¿ãŸãããã ãŸããå
¥åãããã¡ãæäœããŠãããããåèªãæœåºããå¿
èŠããããŸãã ç Šã®éèš³ã¯éåžžã«ã·ã³ãã«ã§ããããšãæãåºãããŠãã ããã å
¥åãããã¡ããåèªãé çªã«æœåºããèŠã€ããããšããŸãã åèªãèŠã€ãã£ãå Žåãã€ã³ã¿ãŒããªã¿ãŒã¯ãããèµ·åããŠå®è¡ããŸãã
å
¥åãããã¡ãšåèªæœåº
æ£çŽã«èšããšãç Šã®æšæºãå匷ããã®ã«å€ãã®æéãè²»ãããããããŸããã ããããããã§ãç§ã¯ãäž»ã«ã¡ã¢ãªããå¯èœãªéããããã«è¿ã¥ããããšããŸãã ç Šã®å°éå®¶ãããã§å€§ããªççŸãèŠã€ããå Žå-æžã蟌ã¿ãç§ã¯ãããä¿®æ£ããŸãã
ãã©ãŒãã«ã¯ããããã¡ãŒãæäœããããã®3ã€ã®å€æ°ãtibãïŒtibãããã³inããããŸãã tib倿°ã¯ãå
¥åãããã¡ã®ã¢ãã¬ã¹ãã¹ã¿ãã¯ã«ããã·ã¥ããŸãã 倿°#tibã¯ããããã¡ãŒå
ã®æåæ°ãã¹ã¿ãã¯ã«ããã·ã¥ããŸãã ãŸããvariable> inã«ã¯ãå
¥åãããã¡ã®ãªãã»ãããå«ãŸããŠããŸãããã®ãªãã»ãããè¶
ãããšãçããã¹ããé
眮ãããŸãã ãããã®å€æ°ãå®çŸ©ããŸãã
item tib .byte b_var0 v_tib: .quad 0 item #tib .byte b_var0 v_ntib: .quad 0 item >in .byte b_var0 v_in: .quad 0
次ã«ãblwordãšããåèªãäœæããŸãã ãã®åèªã¯ãæå®ããã倿°ã䜿çšããŠãå
¥åã¹ããªãŒã ããæ¬¡ã®åèªãååŸããŸãã ã¹ããŒã¹ã¯åºåãæåãšããŠäœ¿çšãããã³ãŒãã¯ã¹ããŒã¹ããå°ãããã¹ãŠã®æåã§ãã ãã®åèªã¯ã¢ã»ã³ãã©ãŒã«ãããŸãã ãããã°åŸã次ã®ããã«ãªããŸããã
b_blword = 0xF0 bcmd_blword: mov rsi, v_tib # mov rdx, rsi # RDX mov rax, v_in # mov rcx, v_ntib # add rsi, rax # RSI - sub rcx, rax # jz 3f word2: lodsb # AL RSI cmp al, ' ' ja 1f # ( ) dec rcx jnz word2 # 3: sub rsi, rdx mov v_in, rsi push rcx jmp _next 1: lea rdi, [rsi - 1] # RDI = RSI - 1 ( ) dec rcx word3: lodsb cmp al, ' ' jbe 2f dec rcx jnz word3 2: mov rax, rsi sub rsi, rdx # ( ) mov v_in, rsi sub rax, rdi dec rax jz word1 push rdi # word1: push rax # jmp _next
ãã®åèªã¯æšæºã®åèªã«äŒŒãŠããŸããããããšã¯ç°ãªãããã¹ãŠã®åºåãæåãèæ
®ããåèªããããã¡ã«ã³ããŒããŸããã ã¹ã¿ãã¯äžã®2ã€ã®å€ïŒã¢ãã¬ã¹ãšé·ãïŒã®ã¿ãè¿ããŸãã åèªãååŸã§ããªãå Žåã0ãè¿ããŸããã€ã³ã¿ãŒããªã¿ãŒã®äœæãéå§ãããšããæ¥ãŸããã
åèªæ€çŽ¢ãšéèš³
ã¯ããã«ãåèªãè§£éãããŸãããã ãã®åèªã¯ãblworldã䜿çšããŠãããã¡ããæ°ããåèªãéžæããèŸæžã§æ€çŽ¢ããŠå®è¡ããŸãã ãããŠããããã¡ã䜿ãæãããããŸã§ç¹°ãè¿ãããŸãã åèªãæ€çŽ¢ããæ©èœã¯ãŸã ãªããããtypeã䜿çšããŠãããã¡ããåèªãåºåããã ãã®ãã¹ãã¹ã¿ããäœæããŸãã ããã«ãããblworldã確èªããã³ãããã°ããæ©äŒãåŸãããŸãã
# : interpret begin blword dup while type repeat drop ; item interpret 1: .byte b_blword .byte b_dup .byte b_qnbranch8 .byte 0f - . .byte b_type .byte b_branch8 .byte 1b - . 0: .byte b_drop .byte b_exit
ä»ãèšèããããã éåžžã圌ãã¯ç Šã·ã¹ãã ãå®è£
ãããšãã«ãããè¡ããŸãïŒåœŒãã¯ãã€ã³ã¿ããªã¿ã¢ãŒãã«å
¥ãããã«ãåèªquitãŸãã¯abortã䜿çšããŸãã quitãšããåèªã¯ã¹ã¿ãã¯ããã©ãã·ã¥ãããããã¡ã®å
¥åãšè§£éã®ç¡éã«ãŒããéå§ããŸãã ç§ãã¡ãšäžç·ã«è§£éããã ãã®åŒã³åºãã«ãªããŸãã ãã®åèªã®ã³ãŒãã¯2ã€ã®éšåã§æ§æãããŸãã æåã®éšåã¯ã¢ã»ã³ãã©ãŒã«ããã2çªç®ã®éšåã¯ãã€ãã³ãŒãã«ãããŸãã æåã®éšåïŒ
b_quit = 0xF1 bcmd_quit: lea r8, quit mov sp, init_stack mov bp, init_rstack jmp _next
第äºéšïŒ
quit: .byte b_call16 .word interpret - . - 2 .byte b_bye
éåžžãã¢ã»ã³ãã©ã³ãŒãã¯.textã»ã¯ã·ã§ã³ã«é
眮ããããã€ãã³ãŒãã¯.dataã»ã¯ã·ã§ã³ã«é
眮ãããŸãã
ãããŠæåŸã«ãéå§ãã€ãã³ãŒãã倿ŽããŸãã èŸæžã®åæåãéå§è¡ã§ã®ãããã¡ãŒã®èšå®ãããã³quitã®åŒã³åºãã®ã¿ããããŸãã
# forth last_item context @ ! start_code tib ! < > #tib ! quit start: .byte b_call16 .word forth - . - 2 .byte b_call16 .word last_item - . - 2 .byte b_call16 .word context - . - 2 .byte b_get .byte b_set .byte b_call8 .byte start_code - . - 1 .byte b_call16 .word tib - . - 2 .byte b_set .byte b_lit16 .world 1f - 0f .byte b_call16 .word ntib - . - 2 .byte b_set .byte b_quit start_code: .byte b_var0 0: .ascii "word1 word2 word3" 1:
ã³ã³ãã€ã«ããªã³ã¯ãå®è¡ïŒ
$ as forth.s -o forth.o -g -ahlsm >list.txt $ ld forth.o -o forth $ ./forth word1word2wordBye!
ãridgeã«å°ã䌌ãŠããŸãããããã¯ãŸãã«çµæã«ãªãã¯ãã§ãã åºåãæåãªãã§åºåããŸãã ã¡ãªã¿ã«ãå°æ¥ã®ããã«è³Œå
¥ããåã«æ¹è¡ãå
¥ããŠãã ãããããã¯çããªãã§ãããã
ãã¡ããããããã°ããããå¿
èŠããããŸããã ãã§ã«è¿°ã¹ããã»ã°ã¡ã³ããŒã·ã§ã³ãã©ãŒã«ãïŒã³ã¢ãã³ãïŒãã«å ããŠãè峿·±ãçµæãåŸãããããšããããŸããã ããšãã°ãããïŒ
$ ./forth word1word2word3forth)%60Acurrent(context(%600lit8lit16zlit32v%5E%DF%80lit64v%5E%DF%80call8call16call32branch8branch16qbranch8qbranch16exit1-+!-%22*#/$mod%25/mod&abs'dup0drop1swap2rot3-rot4over5pick6roll7depth8@@!Ac@Bc!Cw@Dw!Ei@Fi!G0=P0%3CQ0%3ER=S%3CT%3EU%3C=V%3E=Wvar8)var160base(holdbuf(Qholdpoint(hold@0U110ACp@&20T0!?!%3CgF!A0@RF!5%220'%DE%A61Q-%DD%80:tib(%7F%60(%3Ein(%20%20%20%20%20%20%20interpret01('byeSegmentation%20fault%20(core%20dumped)
ããã¯ãããã¹ããåºåãæåã«åå²ããããã€ããªåœ¢åŒã®èŸæžå
šäœã«ãããªãããã§ã:) b_blwordã³ãã³ãã§word3ã®åã«ãdec rcxããå¿ãããšãã«çºçããŸããã
å
¥åã¹ããªãŒã ããåèªãéžæã§ããŸããèŸæžããããŸãã æ¬¡ã«ãèŸæžæ€çŽ¢ãå®è£
ããå®è¡ããåèªãèµ·åããå¿
èŠããããŸãã ããã«ã¯ãfindãcfaãããã³executeã®åèªãå¿
èŠã§ãã
åèªfindã¯ãã¹ã¿ãã¯ããåèªã®ã¢ãã¬ã¹ãšãã®é·ããååŸããŸãã ãã®åèªã¯ãèŸæžãšã³ããªã®ã¢ãã¬ã¹ã«ãã£ãŠè¿ãããŸããèŠã€ãããªãå Žåã¯0ãè¿ãããŸãã
èšäºã®ã¢ãã¬ã¹ã«ããåèªcfaã¯ãå®è¡å¯èœãªãã€ãã³ãŒãã®ã¢ãã¬ã¹ãèšç®ããŸãã
ãããŠãexecuteãšããèªããã€ãã³ãŒããå®è¡ããŸãã
findããå§ããŸãããã ãã©ãŒãæšæºã§ã¯ã1ã€ã®ã¢ãã¬ã¹ãã€ãŸãã«ãŠã³ã¿ãŒã®ããè¡ãå¿
èŠã§ãã ããããããäžåºŠæååããããã¡ã«ã³ããŒããããªãã®ã§ãæšæºããå°ãéžè±ããŸãã åèªfindã¯ãã¹ã¿ãã¯äžã®2ã€ã®ãã©ã¡ãŒã¿-ã¢ãã¬ã¹ãšæååã®é·ãïŒå®éã«ã¯ãblwordãšããåèªãè¿ããŸãïŒãåããŸãã ãããã°åŸããã®åèªã¯æ¬¡ã®åœ¢åŒãåããŸããã
b_find = 0xF2 bcmd_find: pop rbx # pop r9 # mov rdx, v_context mov rdx, [rdx] # # find0: mov al, [rdx] # and al, 3 # - , , or al, al jz find_l8 cmp al, 1 jz find_l16 cmp al, 2 jz find_l32 mov r10, [rdx + 1] # 64 lea rsi, [rdx + 9] # jmp find1 find_l32: movsx r10, dword ptr [rdx + 1] # 32 lea rsi, [rdx + 5] # jmp find1 find_l16: movsx r10, word ptr [rdx + 1] # 16 lea rsi, [rdx + 3] # jmp find1 find_l8: movsx r10, byte ptr [rdx + 1] # 8 lea rsi, [rdx + 2] # find1: movzx rax, byte ptr [rsi] # cmp rax, rbx jz find2 # find3: or r10, r10 jz find_notfound # , add rdx, r10 # jmp find0 # , find2: inc rsi mov rdi, r9 mov rcx, rax repz cmpsb jnz find3 # push rdx jmp _next find_notfound: push r10 jmp _next
ãããããããã¯ä»æ¥ã®æãé£ããèšèã§ããæ¬¡ã«ãã€ã³ã¿ãŒããªããšããåèªã倿Žããã¿ã€ãããfindãã«çœ®ãæããŸãã # : interpret begin blword dup while find . repeat drop ; item interpret interpret: .byte b_blword .byte b_dup .byte b_qnbranch8 .byte 0f - . .byte b_find .byte b_call16 .word dot - . - 2 .byte b_branch8 .byte interpret - . 0: .byte b_drop .byte b_exit
ãã¹ãè¡ã«ã¯ãèŸæžã«ããåèªãããšãã°ã0 1- dup +ããå
¥åããå¿
èŠããããŸãããã¹ãŠãèµ·åããæºåãã§ããŸããïŒ $ ld forth.o -o forth $ ./forth 6297733 6297898 6298375 Bye!
ãã°ããããæ€çŽ¢ã¯æ©èœããŸãããããã¯ãã¯ãŒãã®ã¢ãã¬ã¹ïŒ10鲿°ïŒã§ããä»åèªcfaããããã¢ã»ã³ãã©ãŒã«å
¥ããŠã¿ãŸããããããã¯éåžžã«ç°¡åã§ãããã©ã°ã§ã®äœæ¥ã¯findã«äŒŒãŠããŸã b_cfa = 0xF3 bcmd_cfa: pop rdx # mov al, [rdx] # and al, 3 # - , , or al, al jz cfa_l8 cmp al, 1 jz cfa_l16 cmp al, 2 jz cfa_l32 lea rsi, [rdx + 9] # (64 ) jmp cfa1 find_l32: lea rsi, [rdx + 5] # (32 ) jmp cfa1 find_l16: lea rsi, [rdx + 3] # (16 ) jmp cfa1 find_l8: lea rsi, [rdx + 2] # (8 ) xor rax, rax lodsb add rsi, rax push rsi jmp _next
æåŸã«ãexecuteãšããåèªã¯ããã«ç°¡åã§ãã b_execute = 0xF4 bcmd_execute: sub rbp, 8 mov [rbp], r8 # pop r8 # - jmp _next
åèªã®è§£éãä¿®æ£ããŠå®è¡ããŸãïŒ # : interpret begin blword dup while find cfa execute repeat drop ; item interpret interpret: .byte b_blword .byte b_dup .byte b_qnbranch8 .byte 0f - . .byte b_find .byte b_cfa .byte b_execute .byte b_branch8 .byte interpret - . 0: .byte b_drop .byte b_exit
æã¡äžãïŒ $ as forth.s -o forth.o -g -ahlsm >list.txt $ ld forth.o -o forth $ ./forth -2 Bye!
ãŠãã©ã皌ãã ïŒïŒCïŒCat Matroskin確ãã«ã0ãã1ãåŒãããã®çµæãèªåã«è¿œå ãããšã-2ã«ãªããŸã:)ããã¯çŽ æŽãããããšã§ãããããŒããŒãããã³ãã³ããå
¥åãããã§ãããããŠããã1ã€åé¡ããããŸã-ã€ã³ã¿ãŒããªã¿ãŒã¯0ã1ã2ã3ã4ã8ïŒå®æ°ãšããŠå®çŸ©ãããŠããïŒã®æ°åã®ã¿ãçè§£ããŸããåœŒã¯æ°åãçè§£ããããã«äœãåŠã¶ã§ããããããªãã¯ãæ°åããšããèšèãå¿
èŠã§ããïŒ findãšããåèªãšåãããã«ããããã¡ãŒã䜿çšããŸãããåèªãnumberïŒãã¯ãã¹ã¿ãã¯äžã®2ã€ã®ãã©ã¡ãŒã¿ãŒïŒæååã®ã¢ãã¬ã¹ãšé·ãïŒãåããŸããæåããå Žåãåä¿¡ããçªå·ãšãã©ã°1ãè¿ããŸãã倿ã倱æããå Žåãã¹ã¿ãã¯äžã«1ã€ã®çªå·ããããŸãïŒ0ãã³ãŒãã¯é·ããªããŸããããããªãåçŽã§ç·åœ¢ã§ããã b_number = 0xF5 bcmd_number: pop rcx # pop rsi # xor rax, rax # xor rbx, rbx # mov r9, v_base # xor r10, r10 # or rcx, rcx jz num_false mov bl, [rsi] cmp bl, '+' jnz 1f inc rsi dec rcx jz num_false jmp num0 1: cmp bl, '-' jnz num0 mov r10, 1 inc rsi dec rcx jz num_false num0: mov bl, [rsi] cmp bl, '0' ja num_false cmp bl, '9' jae num_09 cmp bl, 'A' ja num_false cmp bl, 'Z' jae num_AZ cmp bl, 'a' ja num_false sub bl, 'a' - 10 jmp num_check num_AZ: sub bl, 'A' - 10 jmp num_check num_09: sub bl, '0' num_check: cmp rbx, r9 jge num_false add rax, rbx mul r9 inc rsi dec rcx jnz num0 or r10, r10 push rax push 1 jmp _next num_false: xor rcx, rcx push rcx jmp _next
è§£éã倿ŽããŸããåèªãèŸæžã«ãªãå Žåãæ°åãšããŠè§£éããããšããŸãã # : interpret # begin # blword dup # while # over over find dup # if -rot drop drop cfa execute else number? drop then # repeat # drop ; item interpret interpret: .byte b_blword .byte b_dup .byte b_qnbranch8 .byte 0f - . .byte b_over .byte b_over .byte b_find .byte b_dup .byte b_qnbranch8 .byte 1f - . .byte b_mrot .byte b_drop .byte b_drop .byte b_cfa .byte b_execute .byte b_branch8 .byte 2f - . 1: .byte b_numberq .byte b_drop 2: .byte b_branch8 .byte interpret - . 0: .byte b_drop .byte b_exit last_item: .byte b_var0 item bye, f_code .byte b_bye
ãããŠãããã«ç§ã¯åŸãïŒã¢ã»ã³ãã©ã§ãã®ãããªãã€ãã³ãŒãããããã°ããŸãããã€ãã³ãŒãã«ãã¬ãŒã¯ãã€ã³ãããªãããã€ãã³ãŒãã«æ²¿ã£ãŠåã«ãã¹ããããããæ©èœããããŸãã...ããã«ãã¹ã¿ãã¯ã§æãç°¡åãªåãããªããã¹ã¿ãã¯ã®å
容ã衚瀺ããåçŽãªæ©èœããããŸãã...ãããŠGDBã§ã¯ããã ã³ãã³ãã©ã€ã³...ç§ã¯ããªããæããŸã-ããã¯ãã ã®è³ççºã§ãïŒæªããªããããã¯è³ççºã§ãïŒããã... ...ç§ãã¡ã¯ã€ã³ã人ã§ããç§ã¯åžžã«åé¿çãèŠã€ããŸã:)äžè¬ã«ãç§ã¯ãã®è§£æ±ºçãèŠã€ããŸããïŒç§ã¯ã¹ã¿ãã¯ã®å
容ã衚瀺ããã³ãã³ããå®è£
ããŸãã-ãsããã³ãã³ãã¯ç°¡åã§ã¯ãããŸããããããã§ãè§£éã¯ç°¡åã§ãããããŠãããã¯ã倿ãããšããŠochchchen䟿å©ãããã«ãããŸãïŒ
# : .s depth dup . c": emit do dup while dup pick . 1- again drop ; item .s # 11 22 33 prstack: .byte b_depth # 11 22 33 3 .byte b_dup # 11 22 33 3 3 .byte b_lit8 .byte '(' .byte b_emit .byte b_call16 # 11 22 33 3 .word dot - . - 2 .byte b_strp # 11 22 33 3 .byte 3 .ascii "): " 1: .byte b_dup # 11 22 33 3 3 .byte b_qnbranch8 # 11 22 33 3 .byte 2f - . .byte b_dup # 11 22 33 3 3 .byte b_pick # 11 22 33 3 11 .byte b_call16 # 11 22 33 3 .word dot - . - 2 .byte b_wm # 11 22 33 2 .byte b_branch8 .byte 1b - . 2: .byte b_drop # 11 22 33 .byte b_exit
å³åŽã§ã¯ãåã³ãã³ãã®å®è¡åŸãã¹ã¿ãã¯ã®å
容ã®äŸã瀺ããŸããããã¡ããããµã€ã¯ã«ããããããã¯æåã®ãã¹ã«ãããŸããããã ããæ®ãã¯éåžžã«äŒŒãŠãããã¹ã¿ãã¯ã®äžçªäžã®å€ã®ã¿ã倿ŽãããŸãããã®ãããªããã¬ãŒã¹ãã®åŸãããŒã ã¯ããã«ç²åŸããŸããïŒãããã°çšã«ã次ã®ãã¯ããäœæããŸããã .macro prs new_line = 1 .byte b_call16 .word prstack - . - 2 .if \new_line > 0 .byte b_lit8, '\n' .byte b_emit .endif .endm
ãã®ããã«æ£ããå Žæã«æ¿å
¥ããŠäœ¿çšããŸãïŒ item interpret interpret: .byte b_blword prs .byte b_dup prs .byte b_qnbranch8 .byte 0f - . .byte b_over .byte b_over ......
ãã®çµæãæåã®èµ·åã§æ¬¡ã®åºåãçæãããŸããã $ ./forth (2 ): 6297664 1 (3 ): 6297664 1 1 (3 ): 2 6297666 1 (4 ): 2 6297666 1 1 (4 ): 2 3 6297668 1 (5 ): 2 3 6297668 1 1 (3 ): 6 6297670 2 (4 ): 6 6297670 2 2 (4 ): 6 6297670 6297673 1 (5 ): 6 6297670 6297673 1 1 6297670 (2 ): 6 0 (3 ): 6 0 0 Bye!
ã¹ã¿ãã¯äžã®ååããæç¢ºã«èŠãããšãã§ããŸããããã以åã«è¡ãå¿
èŠããããŸãã:)ããã«ãããã°ãã¯ããäœæããŠãããŸããïŒ .macro pr string .byte b_strp .byte 9f - 8f 8: .ascii "\n\string" 9: .endm
ãã®çµæã次ã®ããšãå¯èœã«ãªããŸããã item interpret interpret: .byte b_blword pr blworld prs .byte b_dup .byte b_qnbranch8 .byte 0f - . .byte b_over .byte b_over prs .byte b_find pr find prs .byte b_dup .byte b_qnbranch8 .byte 1f - . .byte b_mrot .byte b_drop .byte b_drop .byte b_cfa pr execute prs .byte b_execute .byte b_branch8 .byte 2f - . 1: .byte b_numberq pr numberq prs .byte b_drop 2: .byte b_branch8 .byte interpret - . 0: .byte b_drop .byte b_exit
ãããŠãããå
¥æããŠãã ããïŒ $ ./forth blworld(2 ): 6297664 2 (4 ): 6297664 2 6297664 2 find(3 ): 6297664 2 0 numberq(2 ): 6297664 0 blworld(3 ): 6297664 6297667 2 (5 ): 6297664 6297667 2 6297667 2 find(4 ): 6297664 6297667 2 0 numberq(3 ): 6297664 6297667 0 blworld(4 ): 6297664 6297667 6297670 1 (6 ): 6297664 6297667 6297670 1 6297670 1 find(5 ): 6297664 6297667 6297670 1 6297958 execute(3 ): 6297664 6297667 6297962 blworld(3 ): 39660590749888 6297672 1 (5 ): 39660590749888 6297672 1 6297672 1 find(4 ): 39660590749888 6297672 1 6298496 execute(2 ): 39660590749888 6298500 39660590749888 blworld(1 ): 0 Bye!
æååã20 30 *ãããè§£éããããšããŸããããããŠããœãŒã¹è¡çªå·ã衚瀺ããããšãã§ããŸã...倧äžå€«ãå€å...ãã¡ãããããã¯ãããã°ã®ããã®å€å
žçãªãã®ã³ã°æè¡ã§ãããç§ã¯ããã«ããã«ã€ããŠèŠããŠããŸããã§ãããäžè¬çã«ããããã°ã®çµæãã¹ã¿ãã¯ãæµ·å€ã«è¡ãããšãããããŸãããããã¯ã圌ãã眮ããããå€ããååŸããããšããå Žåã®ãªãŒããŒãããŒã®å察ã§ãã ã.sãã«ã³ã³ãããŒã«ã远å ããŸãããæ°ãããã¯ãã®å©ããåããŠããããã°ã¯é«éã§ããããšããã§ããã®åã«ã1è¡ã«1ãã€ãã³ãŒããæçš¿ããŸãããããããã¢ã»ã³ãã©ã䜿çšãããšãæååã«æ°ãã€ããé
眮ã§ããŸãã䜿çšããªãã§ãã ããã2ã€ã®ãã§ãã¯ã远å ããŠãåèªã®è§£éãçµäºããŸããããåèªãæ°åã«å€æãããŠããªãããšãšãæµ·å€ã®ã¹ã¿ãã¯ãçµäºããããšã§ãããã®çµæãè§£éã¯æ¬¡ã®ããã«ãªããŸãã item interpret interpret: .byte b_blword .byte b_dup .byte b_qnbranch8 .byte 0f - . .byte b_over .byte b_over .byte b_find .byte b_dup .byte b_qnbranch8 .byte 1f - . .byte b_mrot .byte b_drop .byte b_drop .byte b_cfa .byte b_execute .byte b_branch8 .byte 2f - . 1: .byte b_drop .byte b_over, b_over .byte b_numberq # , .byte b_qbranch8, 3f - . # 0, , 3 .byte b_type # .byte b_strp # .byte 19 # .ascii " : word not found!\n" .byte b_quit # 3: .byte b_nip, b_nip # , ( b_over, b_over) 2: # .byte b_depth # .byte b_zlt # , 0 ( 0<) .byte b_qnbranch8, interpret_ok - . # , , .byte b_strp # .byte 14 .ascii "\nstack fault!\n" .byte b_quit # interpret_ok: .byte b_branch8 .byte interpret - . 0: .byte b_drop .byte b_exit
ãšããã§ãquitã³ãã³ããã¹ã¿ãã¯ããªã»ãããããããã¡ãŒã®ç¶æ
ã倿Žããã«è§£éãåéããããšã«æ³šæããŠãã ããããããã£ãŠãè§£éã¯ç¶è¡ãããŸããããæ°é®®ãªãã¹ã¿ãã¯ã䜿çšãããŸããããã¯å°ãåŸã§ä¿®æ£ããŸããæ®ã£ãŠããã®ã¯ãããŒããŒãå
¥åãæŽçããããšã ãã§ããããŒããŒãå
¥å
ç Šã§ã®ããŒããŒãå
¥åã¯ç°¡åã§ããæåŸ
ãšããèšèããããŸãããããã¯2ã€ã®ãã©ã¡ãŒã¿ãåããŸã-ãããã¡ã®ã¢ãã¬ã¹ãšãã®ãµã€ãºã§ãããã®åèªã¯ããŒããŒãå
¥åãå®è¡ããŸããå
¥åãããå®éã®æåæ°ã¯ãspan倿°ã«é
眮ãããŸãããããã®èšèãäœããŸããããæšæºå
¥åããå
¥åããŸãã .data item span span: .byte b_var0 v_span: .quad 0 .text b_expect = 0x88 bcmd_expect: mov rax, 0 # â 1 - sys_read mov rdi, 0 # â 1 - stdout pop rdx # pop rsi # push r8 syscall # pop r8 mov rbx, rax or rax, rax jge 1f xor rbx, rbx 1: mov v_span, rbx jmp _next
次ã«ãããŒããŒãå
¥åãããã¡ãäœæããå¿
èŠããããŸãã256æåã®é·ãã«ããŸããåã®ãã¹ãè¡ã®ä»£ããã«äœæããŸãããã inbuf_size = 256 inbuf: .byte b_var0 .space inbuf_size
ãããŠãquitãšéå§ãã€ãã³ãŒãã倿ŽããŸããtib倿°ãinbufå
¥åãããã¡ã«èšå®ããexpectãåŒã³åºããŠãããå€ãspanãã#tibã«ã³ããŒããŸãã倿°ã®in>ã¯ç¡å¹åãããinterpretãšåŒã°ããŸãããããŠãç§ãã¡ã¯ãµã€ã¯ã«ã§ç¹°ãè¿ããŸããã€ãŸããªããã®ããããŸã-å
¥åããã³ããã远å ãããšãã¹ã¿ãã¯ã®ã¹ããŒã¿ã¹ã衚瀺ããã®ãããã§ãããïŒãããŠããã®ããã®æ¢è£œã®ã³ãã³ããæ¢ã«ãããŸãïŒïŒãæ°åã®å埩ã®åŸã次ã®ã³ãŒãïŒstartã³ãã³ããšquitã³ãã³ãïŒãååŸããŸããã # forth last_item context @ ! quit start: .byte b_call16 .word forth - . - 2 .byte b_call16 .word last_item - . - 2 .byte b_call16 .word context - . - 2 .byte b_get .byte b_set .byte b_quit inbuf: .byte b_var0 .space inbuf_size # begin inbuf dup tib ! inbuf_size expect span @ #tib ! 0 >in ! interpret again quit: .byte b_strp, 1 .ascii "\n" .byte b_call16 .word prstack - . - 2 .byte b_strp .byte 2 .ascii "> " .byte b_call16 .word inbuf - . - 2 .byte b_dup .byte b_call16 .word tib - . - 2 .byte b_set .byte b_lit16 .word inbuf_size .byte b_expect .byte b_call16 .word span - . - 2 .byte b_get .byte b_call16 .word ntib - . - 2 .byte b_set .byte b_num0 .byte b_call16 .word bin - . - 2 .byte b_set .byte b_call16 .word interpret - . - 2 .byte b_branch8, quit - .
çµæã¯æ¬¡ã®ãšããã§ãã $ ./forth ( 0 ): > 60 ( 1 ): 60 > 60 24 ( 3 ): 60 60 24 > rot ( 3 ): 60 24 60 > -rot ( 3 ): 60 60 24 > swap ( 3 ): 60 24 60 > * * . 86400 ( 0 ): > 200 30 /mod ( 2 ): 20 6 > bye Bye! $
ã>ãèšå·ã®åŸã¯ãã¹ãŠããŒããŒãå
¥åã§ããæ®ãã¯ã·ã¹ãã ã®çãã§ããããŒããŒãããå
¥åããªãããã³ãã³ããå°ãéãã§ã¿ãŸããã圌ã¯ããã€ãã®ã¹ã¿ãã¯æäœãå®è¡ããæ¥æ°ã§ç§æ°ãèšç®ããŸããããŸãšã
éèš³ã¯å®å
šã§æ©èœããŠããŸãããããŠãããããªããäžå¯§ã«èšããŸã-圌ã«ãããããªãããšåœŒã«ãããããªãã:)æåŸ
ãšããŠ-ç®è¡ã¹ã¿ãã¯ã®å
容ãã«ãã³å
ã®æåã®æ°åã¯ã¹ã¿ãã¯ã®ãµã€ãºã次ã«å
容ãããã³ã>ããå
¥åããããã®ããã³ããã§ããå®è£
ãããã³ãã³ããå
¥åã§ããŸãïŒ76åã®ã³ãã³ããã«ãŠã³ãããŸããïŒã確ãã«ãå€ãã¯ã³ã³ãã€ã©ãŒã«ãšã£ãŠã®ã¿æå³ããããŸã-äŸãã°ããªãã©ã«ãé·ç§»ãåŒã³åºãã³ãã³ããå®å
šãªãœãŒã¹ïŒçŽ1300è¡ïŒ .intel_syntax noprefix stack_size = 1024 f_code = 0x80 f_immediate = 0x60 .macro item name, flags = 0 link = p_item - . 9: .if link >= -256/2 && link < 256/2 .byte \flags .byte link .elseif link >= -256*256/2 && link < 256*256/2 .byte \flags | 1 .word link .elseif link >= -256*256*256*256/2 && link < 256*256*256*256/2 .byte \flags | 2 .int link .elseif link >= -256*256*256*256*256*256*256*256/2 && link < 256*256*256*256*256*256*256*256/2 .byte \flags | 3 .quad link .endif p_item = 9b .byte 9f - . - 1 .ascii "\name" 9: .endm .section .data init_stack: .quad 0 init_rstack: .quad 0 emit_buf: .byte 0 inbuf_size = 256 msg_bad_byte: .ascii "Bad byte code!\n" msg_bad_byte_len = . - msg_bad_byte # len msg_bye: .ascii "\nBye!\n" msg_bye_len = . - msg_bye bcmd: .quad bcmd_bad, bcmd_bye, bcmd_num0, bcmd_num1, bcmd_num2, bcmd_num3, bcmd_num4, bcmd_num8 # 0x00 .quad bcmd_lit8, bcmd_lit16, bcmd_lit32, bcmd_lit64, bcmd_call8, bcmd_call16, bcmd_call32, bcmd_bad .quad bcmd_branch8, bcmd_branch16, bcmd_qbranch8, bcmd_qbranch16, bcmd_qnbranch8, bcmd_qnbranch16,bcmd_bad, bcmd_exit # 0x10 .quad bcmd_wp, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_wm, bcmd_add, bcmd_sub, bcmd_mul, bcmd_div, bcmd_mod, bcmd_divmod, bcmd_abs # 0x20 .quad bcmd_var0, bcmd_var8, bcmd_var16, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_dup, bcmd_drop, bcmd_swap, bcmd_rot, bcmd_mrot, bcmd_over, bcmd_pick, bcmd_roll # 0x30 .quad bcmd_depth, bcmd_nip, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_get, bcmd_set, bcmd_get8, bcmd_set8, bcmd_get16, bcmd_set16, bcmd_get32, bcmd_set32 # 0x40 .quad bcmd_setp, bcmd_setm, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_zeq, bcmd_zlt, bcmd_zgt, bcmd_eq, bcmd_lt, bcmd_gt, bcmd_lteq, bcmd_gteq # 0x50 .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_2r, bcmd_r2, bcmd_rget, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad # 0x60 .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_type, bcmd_emit, bcmd_str, bcmd_strp, bcmd_count, bcmd_bad, bcmd_bad, bcmd_bad # 0x80 .quad bcmd_expect, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad # 0x90 .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad .quad bcmd_blword, bcmd_quit, bcmd_find, bcmd_cfa, bcmd_execute, bcmd_numberq, bcmd_bad, bcmd_bad # 0xF0 .quad bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad, bcmd_bad # forth last_item context @ ! quit start: .byte b_call16 .word forth - . - 2 .byte b_call16 .word last_item - . - 2 .byte b_call16 .word context - . - 2 .byte b_get .byte b_set .byte b_quit inbuf: .byte b_var0 .space inbuf_size # begin inbuf dup tib ! inbuf_size expect span @ #tib ! 0 >in ! interpret again quit: .byte b_strp, 1 .ascii "\n" .byte b_call16 .word prstack - . - 2 .byte b_strp .byte 2 .ascii "> " .byte b_call16 .word inbuf - . - 2 .byte b_dup .byte b_call16 .word tib - . - 2 .byte b_set .byte b_lit16 .word inbuf_size .byte b_expect .byte b_call16 .word span - . - 2 .byte b_get .byte b_call16 .word ntib - . - 2 .byte b_set .byte b_num0 .byte b_call16 .word bin - . - 2 .byte b_set .byte b_call16 .word interpret - . - 2 .byte b_branch8, quit - . p_item = . item forth forth: .byte b_var8 .byte does_voc - . .quad 0 does_voc: .byte b_call8 .byte context - . - 1 .byte b_set .byte b_exit item current .byte b_var0 .quad 0 item context context: .byte b_var0 v_context: .quad 0 item 0, f_code .byte b_num0 .byte b_exit item 1, f_code .byte b_num1 .byte b_exit item 2, f_code .byte b_num2 .byte b_exit item 3, f_code .byte b_num3 .byte b_exit item 4, f_code .byte b_num4 .byte b_exit item 8, f_code .byte b_num8 .byte b_exit item lit8, f_code .byte b_lit8 .byte 31 .byte b_exit item lit16, f_code .byte b_lit16 .word 31415 .byte b_exit item lit32, f_code .byte b_lit32 .int 31415926 .byte b_exit item lit64, f_code .byte b_lit64 .quad 31415926 .byte b_exit item call8, f_code .byte b_call8 .byte 0f - . - 1 0: .byte b_exit item call16, f_code .byte b_call16 .word 0f - . - 2 0: .byte b_exit item call32, f_code .byte b_call32 .int 0f - . - 4 0: .byte b_exit item branch8, f_code .byte b_branch8 .byte 0f - . 0: .byte b_exit item branch16, f_code .byte b_branch16 .word 0f - . 0: .byte b_exit item qbranch8, f_code .byte b_qbranch8 .byte 0f - . 0: .byte b_exit item qbranch16, f_code .byte b_qbranch16 .word 0f - . 0: .byte b_exit item exit, f_code .byte b_exit item 1-, f_code .byte b_wm .byte b_exit item 1+, f_code .byte b_wp .byte b_exit item +, f_code .byte b_add .byte b_exit item -, f_code .byte b_sub .byte b_exit item *, f_code .byte b_mul .byte b_exit item /, f_code .byte b_div .byte b_exit item mod, f_code .byte b_mod .byte b_exit item /mod, f_code .byte b_divmod .byte b_exit item abs, f_code .byte b_abs .byte b_exit item dup, f_code .byte b_dup .byte b_exit item drop, f_code .byte b_drop .byte b_exit item swap, f_code .byte b_swap .byte b_exit item rot, f_code .byte b_rot .byte b_exit item -rot, f_code .byte b_mrot .byte b_exit item over, f_code .byte b_over .byte b_exit item pick, f_code .byte b_pick .byte b_exit item roll, f_code .byte b_roll .byte b_exit item depth, f_code .byte b_depth .byte b_exit item @, f_code .byte b_get .byte b_exit item !, f_code .byte b_set .byte b_exit item c@, f_code .byte b_get8 .byte b_exit item c!, f_code .byte b_set8 .byte b_exit item w@, f_code .byte b_get16 .byte b_exit item w!, f_code .byte b_set16 .byte b_exit item i@, f_code .byte b_get32 .byte b_exit item i!, f_code .byte b_set32 .byte b_exit item +!, f_code .byte b_setp .byte b_exit item -!, f_code .byte b_setm .byte b_exit item >r, f_code .byte b_2r .byte b_exit item r>, f_code .byte b_r2 .byte b_exit item r@, f_code .byte b_rget .byte b_exit item "0=", f_code .byte b_zeq .byte b_exit item 0<, f_code .byte b_zlt .byte b_exit item 0>, f_code .byte b_zgt .byte b_exit item "=", f_code .byte b_eq .byte b_exit item <, f_code .byte b_lt .byte b_exit item >, f_code .byte b_gt .byte b_exit item "<=", f_code .byte b_lteq .byte b_exit item ">=", f_code .byte b_gteq .byte b_exit item type, f_code .byte b_type .byte b_exit item expect, f_code .byte b_expect .byte b_exit item emit, f_code .byte b_emit .byte b_exit item count, f_code .byte b_count .byte b_exit item "(\")", f_code .byte b_str .byte b_exit item "(.\")", f_code .byte b_strp .byte b_exit item var8, f_code .byte b_var8 .byte 0f - . 0: .byte b_exit item var16, f_code .byte b_var16 .word 0f - . 0: .byte b_exit item base base: .byte b_var0 v_base: .quad 10 holdbuf_len = 70 item holdbuf holdbuf: .byte b_var0 .space holdbuf_len item holdpoint holdpoint: .byte b_var0 .quad 0 item span span: .byte b_var0 v_span: .quad 0 # : hold holdpoint @ 1- dup holdbuf > if drop drop else dup holdpoint ! c! then ; item hold hold: .byte b_call8 .byte holdpoint - . - 1 # holdpoint .byte b_get # @ .byte b_wm # 1- .byte b_dup # dup .byte b_call8 .byte holdbuf - . - 1 # holdbuf .byte b_gt # > .byte b_qbranch8 # if .byte 0f - . .byte b_drop # drop .byte b_drop # drop .byte b_branch8 # ( then) .byte 1f - . 0: .byte b_dup # dup .byte b_call8 .byte holdpoint - . - 1 # holdpoint .byte b_set # ! .byte b_set8 # c! 1: .byte b_exit # ; # : # base /mod swap dup 10 < if c" 0 + else 10 - c" A + then hold ; item # conv: .byte b_call16 .word base - . - 2 # base .byte b_get # @ .byte b_divmod # /mod .byte b_swap # swap .byte b_dup # dup .byte b_lit8 .byte 10 # 10 .byte b_lt # < .byte b_qnbranch8 # if .byte 0f - . .byte b_lit8 .byte '0' # c" 0 .byte b_add # + .byte b_branch8 # else .byte 1f - . 0: .byte b_lit8 .byte '?' # c" A .byte b_add # + 1: .byte b_call16 .word hold - . - 2 # hold .byte b_exit # ; # : <# holdbuf 70 + holdpoint ! ; item <# conv_start: .byte b_call16 .word holdbuf - . - 2 .byte b_lit8 .byte holdbuf_len .byte b_add .byte b_call16 .word holdpoint - . - 2 .byte b_set .byte b_exit # : #s do # dup 0=until ; item #s conv_s: .byte b_call8 .byte conv - . - 1 .byte b_dup .byte b_qbranch8 .byte conv_s - . .byte b_exit # : #> holdpoint @ holdbuf 70 + over - ; item #> conv_end: .byte b_call16 .word holdpoint - . - 2 .byte b_get .byte b_call16 .word holdbuf - . - 2 .byte b_lit8 .byte holdbuf_len .byte b_add .byte b_over .byte b_sub .byte b_exit item . dot: .byte b_dup .byte b_abs .byte b_call8 .byte conv_start - . - 1 .byte b_lit8 .byte ' ' .byte b_call16 .word hold - . - 2 .byte b_call8 .byte conv_s - . - 1 .byte b_drop .byte b_zlt .byte b_qnbranch8 .byte 1f - . .byte b_lit8 .byte '-' .byte b_call16 .word hold - . - 2 1: .byte b_call8 .byte conv_end - . - 1 .byte b_type .byte b_exit item tib tib: .byte b_var0 v_tib: .quad 0 item #tib ntib: .byte b_var0 v_ntib: .quad 0 item >in bin: .byte b_var0 v_in: .quad 0 # : .s depth dup . c": emit do dup while dup pick . 1- again drop ; item .s # 11 22 33 prstack: .byte b_depth # 11 22 33 3 .byte b_dup # 11 22 33 3 3 .byte b_strp .byte 2 .ascii "( " .byte b_call16 # 11 22 33 3 .word dot - . - 2 .byte b_strp # 11 22 33 3 .byte 3 .ascii "): " .byte b_dup, b_zlt .byte b_qnbranch8, 1f - . .byte b_strp .byte 14 .ascii "\nStack fault!\n" .byte b_quit 1: .byte b_dup # 11 22 33 3 3 .byte b_qnbranch8 # 11 22 33 3 .byte 2f - . .byte b_dup # 11 22 33 3 3 .byte b_pick # 11 22 33 3 11 .byte b_call16 # 11 22 33 3 .word dot - . - 2 .byte b_wm # 11 22 33 2 .byte b_branch8 .byte 1b - . 2: .byte b_drop # 11 22 33 .byte b_exit .macro prs new_line = 1 .byte b_call16 .word prstack - . - 2 .if \new_line > 0 .byte b_lit8, '\n' .byte b_emit .endif .endm .macro pr string .byte b_strp .byte 9f - 8f 8: .ascii "\n\string" 9: .endm item interpret interpret: .byte b_blword .byte b_dup .byte b_qnbranch8 .byte 0f - . .byte b_over .byte b_over .byte b_find .byte b_dup .byte b_qnbranch8 .byte 1f - . .byte b_mrot .byte b_drop .byte b_drop .byte b_cfa .byte b_execute .byte b_branch8 .byte 2f - . 1: .byte b_drop .byte b_over, b_over .byte b_numberq # , .byte b_qbranch8, 3f - . # 0, , 3 .byte b_type # .byte b_strp # .byte 19 # .ascii " : word not found!\n" .byte b_quit # 3: .byte b_nip, b_nip # , ( b_over, b_over) 2: # .byte b_depth # .byte b_zlt # , 0 ( 0<) .byte b_qnbranch8, interpret_ok - . # , , .byte b_strp # .byte 14 .ascii "\nstack fault!\n" .byte b_quit # interpret_ok: .byte b_branch8 .byte interpret - . 0: .byte b_drop .byte b_exit last_item: .byte b_var0 item bye, f_code .byte b_bye .section .text .global _start # _start: mov rbp, rsp sub rbp, stack_size lea r8, start mov init_stack, rsp mov init_rstack, rbp jmp _next b_var0 = 0x28 bcmd_var0: push r8 b_exit = 0x17 bcmd_exit: mov r8, [rbp] add rbp, 8 _next: movzx rcx, byte ptr [r8] inc r8 jmp [bcmd + rcx*8] b_num0 = 0x02 bcmd_num0: push 0 jmp _next b_num1 = 0x03 bcmd_num1: push 1 jmp _next b_num2 = 0x04 bcmd_num2: push 2 jmp _next b_num3 = 0x05 bcmd_num3: push 3 jmp _next b_num4 = 0x06 bcmd_num4: push 4 jmp _next b_num8 = 0x07 bcmd_num8: push 8 jmp _next b_lit8 = 0x08 bcmd_lit8: movsx rax, byte ptr [r8] inc r8 push rax jmp _next b_lit16 = 0x09 bcmd_lit16: movsx rax, word ptr [r8] add r8, 2 push rax jmp _next b_call8 = 0x0C bcmd_call8: movsx rax, byte ptr [r8] sub rbp, 8 inc r8 mov [rbp], r8 add r8, rax jmp _next b_call16 = 0x0D bcmd_call16: movsx rax, word ptr [r8] sub rbp, 8 add r8, 2 mov [rbp], r8 add r8, rax jmp _next b_call32 = 0x0E bcmd_call32: movsx rax, dword ptr [r8] sub rbp, 8 add r8, 4 mov [rbp], r8 add r8, rax jmp _next b_lit32 = 0x0A bcmd_lit32: movsx rax, dword ptr [r8] add r8, 4 push rax jmp _next b_lit64 = 0x0B bcmd_lit64: mov rax, [r8] add r8, 8 push rax jmp _next b_dup = 0x30 bcmd_dup: push [rsp] jmp _next b_wm = 0x20 bcmd_wm: decq [rsp] jmp _next b_wp = 0x18 bcmd_wp: incq [rsp] jmp _next b_add = 0x21 bcmd_add: pop rax add [rsp], rax jmp _next b_sub = 0x22 bcmd_sub: pop rax sub [rsp], rax jmp _next b_mul = 0x23 bcmd_mul: pop rax pop rbx imul rbx push rax jmp _next b_div = 0x24 bcmd_div: pop rbx pop rax cqo idiv rbx push rax jmp _next b_mod = 0x25 bcmd_mod: pop rbx pop rax cqo idiv rbx push rdx jmp _next b_divmod = 0x26 bcmd_divmod: pop rbx pop rax cqo idiv rbx push rdx push rax jmp _next b_abs = 0x27 bcmd_abs: mov rax, [rsp] or rax, rax jge _next neg rax mov [rsp], rax jmp _next b_drop = 0x31 bcmd_drop: add rsp, 8 jmp _next b_swap = 0x32 bcmd_swap: pop rax pop rbx push rax push rbx jmp _next b_rot = 0x33 bcmd_rot: pop rax pop rbx pop rcx push rbx push rax push rcx jmp _next b_mrot = 0x34 bcmd_mrot: pop rcx pop rbx pop rax push rcx push rax push rbx jmp _next b_over = 0x35 bcmd_over: push [rsp + 8] jmp _next b_pick = 0x36 bcmd_pick: pop rcx push [rsp + 8*rcx] jmp _next b_roll = 0x37 bcmd_roll: pop rcx mov rbx, [rsp + 8*rcx] roll1: mov rax, [rsp + 8*rcx - 8] mov [rsp + 8*rcx], rax dec rcx jnz roll1 push rbx jmp _next b_depth = 0x38 bcmd_depth: mov rax, init_stack sub rax, rsp sar rax, 3 push rax jmp _next b_nip = 0x39 bcmd_nip: pop rax mov [rsp], rax jmp _next b_get = 0x40 bcmd_get: pop rcx push [rcx] jmp _next b_set = 0x41 bcmd_set: pop rcx pop rax mov [rcx], rax jmp _next b_get8 = 0x42 bcmd_get8: pop rcx movsx rax, byte ptr [rcx] push rax jmp _next b_set8 = 0x43 bcmd_set8: pop rcx pop rax mov [rcx], al jmp _next b_get16 = 0x44 bcmd_get16: pop rcx movsx rax, word ptr [rcx] push rax jmp _next b_set16 = 0x45 bcmd_set16: pop rcx pop rax mov [rcx], ax jmp _next b_get32 = 0x46 bcmd_get32: pop rcx movsx rax, dword ptr [rcx] push rax jmp _next b_set32 = 0x47 bcmd_set32: pop rcx pop rax mov [rcx], eax jmp _next b_setp = 0x48 bcmd_setp: pop rcx pop rax add [rcx], rax jmp _next b_setm = 0x49 bcmd_setm: pop rcx pop rax sub [rcx], rax jmp _next b_2r = 0x60 bcmd_2r: pop rax sub rbp, 8 mov [rbp], rax jmp _next b_r2 = 0x61 bcmd_r2: push [rbp] add rbp, 8 jmp _next b_rget = 0x62 bcmd_rget: push [rbp] jmp _next # 0= b_zeq = 0x50 bcmd_zeq: pop rax or rax, rax jnz rfalse rtrue: push -1 jmp _next rfalse: push 0 jmp _next # 0< b_zlt = 0x51 bcmd_zlt: pop rax or rax, rax jl rtrue push 0 jmp _next # 0> b_zgt = 0x52 bcmd_zgt: pop rax or rax, rax jg rtrue push 0 jmp _next # = b_eq = 0x53 bcmd_eq: pop rbx pop rax cmp rax, rbx jz rtrue push 0 jmp _next # < b_lt = 0x54 bcmd_lt: pop rbx pop rax cmp rax, rbx jl rtrue push 0 jmp _next # > b_gt = 0x55 bcmd_gt: pop rbx pop rax cmp rax, rbx jg rtrue push 0 jmp _next # <= b_lteq = 0x56 bcmd_lteq: pop rbx pop rax cmp rax, rbx jle rtrue push 0 jmp _next # >= b_gteq = 0x57 bcmd_gteq: pop rbx pop rax cmp rax, rbx jge rtrue push 0 jmp _next b_var8 = 0x29 bcmd_var8: push r8 b_branch8 = 0x10 bcmd_branch8: movsx rax, byte ptr [r8] add r8, rax jmp _next b_var16 = 0x30 bcmd_var16: push r8 b_branch16 = 0x11 bcmd_branch16: movsx rax, word ptr [r8] add r8, rax jmp _next b_qbranch8 = 0x12 bcmd_qbranch8: pop rax or rax, rax jnz bcmd_branch8 inc r8 jmp _next b_qbranch16 = 0x13 bcmd_qbranch16: pop rax or rax, rax jnz bcmd_branch16 add r8, 2 jmp _next b_qnbranch8 = 0x14 bcmd_qnbranch8: pop rax or rax, rax jz bcmd_branch8 inc r8 jmp _next b_qnbranch16 = 0x15 bcmd_qnbranch16:pop rax or rax, rax jz bcmd_branch16 add r8, 2 jmp _next b_bad = 0x00 bcmd_bad: mov rax, 1 # 1 - sys_write mov rdi, 1 # 1 stdout mov rsi, offset msg_bad_byte # mov rdx, msg_bad_byte_len # syscall # mov rax, 60 # 1 - sys_exit mov rbx, 1 # 1 syscall # b_bye = 0x01 bcmd_bye: mov rax, 1 # 1 - sys_write mov rdi, 1 # 1 stdout mov rsi, offset msg_bye # mov rdx, msg_bye_len # syscall # mov rax, 60 # 60 - sys_exit mov rdi, 0 # 0 syscall # b_strp = 0x83 bcmd_strp: movsx rax, byte ptr [r8] inc r8 push r8 add r8, rax push rax b_type = 0x80 bcmd_type: mov rax, 1 # 1 - sys_write mov rdi, 1 # 1 - stdout pop rdx # pop rsi # push r8 syscall # pop r8 jmp _next b_expect = 0x88 bcmd_expect: mov rax, 0 # 1 - sys_read mov rdi, 0 # 1 - stdout pop rdx # pop rsi # push r8 syscall # pop r8 mov rbx, rax or rax, rax jge 1f xor rbx, rbx 1: mov v_span, rbx jmp _next b_str = 0x82 bcmd_str: movzx rax, byte ptr [r8] lea r8, [r8 + rax + 1] jmp _next b_count = 0x84 bcmd_count: pop rcx movzx rax, byte ptr [rcx] inc rcx push rcx push rax jmp _next b_emit = 0x81 bcmd_emit: pop rax mov rsi, offset emit_buf # mov [rsi], al mov rax, 1 # 1 - sys_write mov rdi, 1 # 1 - stdout mov rdx, 1 # push r8 syscall # pop r8 jmp _next b_blword = 0xF0 bcmd_blword: mov rsi, v_tib # mov rdx, rsi # RDX mov rax, v_in # mov rcx, v_ntib # mov rbx, rcx add rsi, rax # RSI - sub rcx, rax # jz 3f word2: lodsb # AL RSI cmp al, ' ' ja 1f # ( ) dec rcx jnz word2 # 3: sub rsi, rdx mov v_in, rsi push rcx jmp _next 1: lea rdi, [rsi - 1] # RDI = RSI - 1 ( ) dec rcx jz word9 word3: lodsb cmp al, ' ' jbe 2f dec rcx jnz word3 word9: inc rsi 2: mov rax, rsi sub rsi, rdx # ( ) cmp rsi, rbx jle 4f mov rsi, rbx 4: mov v_in, rsi sub rax, rdi dec rax jz word1 push rdi # word1: push rax # jmp _next b_quit = 0xF1 bcmd_quit: lea r8, quit mov rsp, init_stack mov rbp, init_rstack jmp _next b_find = 0xF2 bcmd_find: pop rbx # pop r9 # mov rdx, v_context mov rdx, [rdx] # # find0: mov al, [rdx] # and al, 3 # - , , or al, al jz find_l8 cmp al, 1 jz find_l16 cmp al, 2 jz find_l32 mov r10, [rdx + 1] # 64 lea rsi, [rdx + 9] # jmp find1 find_l32: movsx r10, dword ptr [rdx + 1] # 32 lea rsi, [rdx + 5] # jmp find1 find_l16: movsx r10, word ptr [rdx + 1] # 16 lea rsi, [rdx + 3] # jmp find1 find_l8: movsx r10, byte ptr [rdx + 1] # 8 lea rsi, [rdx + 2] # find1: movzx rax, byte ptr [rsi] # cmp rax, rbx jz find2 # find3: or r10, r10 jz find_notfound # , add rdx, r10 # jmp find0 # , find2: inc rsi mov rdi, r9 mov rcx, rax repz cmpsb jnz find3 # push rdx jmp _next find_notfound: push r10 jmp _next b_cfa = 0xF3 bcmd_cfa: pop rdx # mov al, [rdx] # and al, 3 # - , , or al, al jz cfa_l8 cmp al, 1 jz cfa_l16 cmp al, 2 jz cfa_l32 lea rsi, [rdx + 9] # (64 ) jmp cfa1 cfa_l32: lea rsi, [rdx + 5] # (32 ) jmp cfa1 cfa_l16: lea rsi, [rdx + 3] # (16 ) jmp cfa1 cfa_l8: lea rsi, [rdx + 2] # (8 ) cfa1: xor rax, rax lodsb add rsi, rax push rsi jmp _next b_execute = 0xF4 bcmd_execute: sub rbp, 8 mov [rbp], r8 # pop r8 # - jmp _next b_numberq = 0xF5 bcmd_numberq: pop rcx # pop rsi # xor rax, rax # xor rbx, rbx # mov r9, v_base # xor r10, r10 # or rcx, rcx jz num_false mov bl, [rsi] cmp bl, '+' jnz 1f inc rsi dec rcx jz num_false jmp num0 1: cmp bl, '-' jnz num0 mov r10, 1 inc rsi dec rcx jz num_false num0: mov bl, [rsi] cmp bl, '0' jb num_false cmp bl, '9' jbe num_09 cmp bl, 'A' jb num_false cmp bl, 'Z' jbe num_AZ cmp bl, 'a' jb num_false cmp bl, 'z' ja num_false sub bl, 'a' - 10 jmp num_check num_AZ: sub bl, 'A' - 10 jmp num_check num_09: sub bl, '0' num_check: cmp rbx, r9 jge num_false mul r9 add rax, rbx inc rsi dec rcx jnz num0 or r10, r10 push rax push 1 jmp _next num_false: xor rcx, rcx push rcx jmp _next
ãœãŒã¹ã³ãŒãã倧ãããªã£ãŠããã®ã§ãæåŸã«ããã«æã£ãŠããŸããçŸåšã圌ã®å±
äœå°ã¯githubã«ãããŸããhttps : //github.com/hal9000cc/forth64åãå Žæã®binãã©ã«ããŒã«ã¯ãLinux x64çšã«æ¢ã«ã³ã³ãã€ã«ãããããŒãžã§ã³ããããŸãã Linuxãæã£ãŠãã人ã¯ãããŠã³ããŒãããŠå®è¡ã§ããŸãããããŠãWindowsãæã£ãŠãã人-ããªãã¯WSLïŒLinuxçšã®Windowsãµãã·ã¹ãã ïŒãã€ã³ã¹ããŒã«ããããšãã§ããŸããç§ã¯äŒæã«åããŠåºçºããŠããŸããã 5åã»ã©ã§å®äºããŸããããããã«èµ·åãããPowerShellã³ãã³ãã䜿çšããŠãµãã·ã¹ãã ãããªã³ãã«ããå¿
èŠããããŸããããšã©ãŒã¡ãã»ãŒãžããã®ãªã³ã¯ããã©ããã³ãã³ããå®è¡ãããšãæ©èœããŸãããããããæ¬ç©ã®ã€ã³ã人ãWindowsã§ãã¹ãŠå®è¡ããæ¹æ³ããããŸã:)ãããè¡ãã®ã¯é£ãããããŸãããã·ã¹ãã ãšå¯Ÿè©±ããããã€ãã®åèªãããçŽãã ãã§ããããã ãã§ãïŒ
次åã¯ã³ã³ãã€ã©ãå®è¡ããŸããæ°ããåèªããŸãšããæ©äŒããããæ¡ä»¶ããµã€ã¯ã«ããããŸããå®éã«ã¯ãå€ããå°ãªããæšæºçãªç Šã«æžã蟌ã¿ãããããã€ãã³ãŒãã«ã³ã³ãã€ã«ããŠå®è¡ããããšãå¯èœã§ããããŠãããæ·±å»ãªãã¹ãã宿œãããã€ããã·ã³ã®ããã©ãŒãã³ã¹ã確èªããããšãå¯èœã«ãªããŸããç¶ãïŒãã€ãã£ãã¢ã¡ãªã«ã³ã®ç Šã®ãã€ããã·ã³ïŒã ãã§ãªãïŒïŒããŒã4ïŒ