From 21855212e5db77104b1179a32ea2e9fc8978ceba Mon Sep 17 00:00:00 2001 From: igor Date: Fri, 19 Dec 2025 15:27:09 +0100 Subject: [PATCH] added --debug to compile with debug info --- a.out | Bin 10968 -> 9128 bytes build/a.asm | 357 +++++++++++++++++++++++++++++++++++------------- build/a.o | Bin 4368 -> 5440 bytes build/hello.asm | 357 +++++++++++++++++++++++++++++++++++------------- build/hello.o | Bin 4384 -> 5456 bytes build/main.asm | 357 +++++++++++++++++++++++++++++++++++------------- build/main.o | Bin 4416 -> 5488 bytes main.py | 24 ++-- 8 files changed, 808 insertions(+), 287 deletions(-) diff --git a/a.out b/a.out index 8fc096a4f6cf1138c8437db97978404737161db2..692068c06232a80da3913784ee2f2a7e6dea0e98 100755 GIT binary patch literal 9128 zcmeI2U2GKB700iQ7Yt6an?Q)wLbX9lHA2{>F{AZlyL5r@ldbf_dGm!y+@tZ@mTY@iqv*-_ z#OqC6fw}^91?mda6{ssvSD>yyU4gm+bp`4Q)D`%DRKOTr`F*&7CEU-9(L25lH?m3r z{=6PTDH7dRoMye$6w^m0n>BZOYy-e>2#FRx#B{eQRxV4sURoC0KM%*7m_G7lbI?j7 z3j!H%>qPy1#uDjb}ky%EZWZ>+L(g?P@FdkC)KpD03R|(plxQ6YSYuKK@hV8j)*q-%mT1ga$w|mUX z1*xD0H1{KIu+KH5*M`_w zizrB;;|9*DNNe@jHxWK?RNHqpeBc;V?g{ugt=;-A9_oMhTj={~7-s@zPxvKp~n z6xJpNv9R|49Vl-Y0Oh;E6MoCvhYvTt?LRMkb07mmn2e0!2Uwarqjg-=I!?oL=N{8W zzGLCX_X5}5iLqvA4R;#s44#gI&dU9(1YOQ+o zi)B!N8Wh3Ig+0droZP<@D1?JYs(4O^<8l^q=Q{vTHQlfXnm{)08@hYma8L47mOvFa zRN$CC?Ewk|PYdM1QkMNT=vQ96RIOItgYuFTr^!BgS8l@FYXJ`!vvOtI6`1&2xJhTk zmAwIgkt%;cx6Qan0(%#dP zoWfg(vzy|4ro1g7zD(g!;_DQ?iuhKAuOs@XE5sjD z_yyu+g*W5xUC`kZh2KJa-qPCqqr`7h_^LVhUBr78|2Xmc6uyOcPT?uyuEMj#-&c5% zbJ%pWHveId_u$68>rZp=KYP5_^Tp27bMU_t-xIC%KLk7iI?Ml0mBC)-e0H8k=HLg3 ztMOT?Xl2uP4kWEyd$KUV%z~4&o%USb%vqSW3kEM%) z0;TOd_3}G2wqS*!Br!Yh2xNAGBlU9@S)F3v!@}I@#X~cR19&|%1C?Z& zsRHH?Pbo7q>7MZP%x$M&Z%AAdD^-`$Y^4vdJv z-uFCc9l|tX>{jUEUrg{i5|@0>M#a$kz6Y7r`M5T`^=4hIw+Ixa@0;LvSv2^;weV^c n4a1KjytRp8v+ieNFsT@Ez2J2t3=|h`zJeQr>o(DNcXj>`0hVL| literal 10968 zcmeI2Uu;uV9LG<$7Q2DA=v+o1p~S0#fjK&eE)whz^xn`VM0t<|y=m976}EP1Zy7Tq zkTf&gl<5m3;va;>_@r-220l3Ggs8Y6CWeGW7em4fn1C-cLNb59bAIRE_RNjMSMN=F z&hLDFf6h7Idv23;_t3WZ%XK~Bg0-ge% z0-ge%0-ge%0-ge%0-ge%0-ge%0{=$^;-gP43;S4?eKS6~E)=d~(}&C`|-)`_kAZfS~{qJ#>Z{wqL7Mq~9p7(2msOcpEcHw}VyQ@@_4tm;PeIuf<0L zM?;LoM<4zGyN=3mEZ*_`!54JFtU$tJk#|}2=GuJzL4uqeD@Uu{ib)IX476Xcl_1Vdbi`w+r^S4&$>#yqe zHDl(_!xsQd9%%*&<@Ay3#Ty2!+iKv!>i}Q$Khg+Y)oSeT4Et`}o(u(ODYSK?+@u+0 zOAF$z+;|A9pqvoA6@5-LsEj%p_6p6g!6mA3RE}$5!(Jk|Vei($bDWqI$Ly`r33KpU z!0!()Lvvw)>Oj{AMV$4(qSZ;tJGB+u?lME&Qk3=zJTw;1$-Yb;5)g1?<3cz zm&JqP>>k%;gH&(^bbCrK-MC|vhqcvsRw4#!+yzaz3y()v8E$%MqHU}JHyF_E3FijE zJ~xnFo3ydT+)s*a;+!7VT0KU_L&wg;xegt>08j9@@VTn5`VnvHgX0?9I34SZL-x3P z#PHUY{(ytEjX^E^4)~_(c*6iF-wod3%g#Prxb+A3dxN_#`8E7ePuh>e9;ZLOKRY{p z8X8FfvI;id=3Gn*dl%Vg7LF55RG=s-S`wM_VkVIoP< zsZ38sX7=TB15_i^lNHvUOg2;KH7SfQBvl*`vk&GoR@zJ!_lRLC59vH2w?Ca1R$(wf zET6LkGNTYkb~Zy^tJu9yxT8*aj3al{trK;No6)3GQW^s`CO zTLzHOW_x#)H|^R|e^bie-!FI9U(7l--Z)V*k);W9Bu7?m+-#Q$<-ruud3V1987W8J zHTx5pEK4PbDX}=&iiyd!=Qi4_K^~hqXdt&4czI2g@N3zuNe_idaKFcVQeb=DgP^ zhVu1B8ZovCEX=Q$BoY%=M0CxfbK2T>Fd2IqJVE%#eEB`p91$sp<@=FhIA?yG8y@vJ zS4%{oHrg1z!?_tgI2T?mqGR}zwVay}@ARj{=(JKC=c~S!!ra3Dt>*s& D8~Fzo diff --git a/build/a.asm b/build/a.asm index 2cc2435..9b91637 100644 --- a/build/a.asm +++ b/build/a.asm @@ -37,104 +37,11 @@ word_r_40: mov [r12], rax ret ret -word_strlen: - mov rax, [r12] ; addr - mov rcx, [r12 + 8] ; len - add r12, 16 ; pop len and addr - mov [r12], rcx ; push len - ret - ret -word_puts: - ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] - mov rax, [r12] ; len or int value - mov rbx, [r12 + 8] ; possible address - cmp rax, 0 - jl puts_print_int - lea r8, [rel data_start] - lea r9, [rel data_end] - cmp rbx, r8 - jl puts_print_int - cmp rbx, r9 - jge puts_print_int - ; treat as string: (addr below len) - mov rdx, rax ; len - mov rsi, rbx ; addr - add r12, 16 ; pop len + addr - test rdx, rdx - jz puts_str_newline_only - mov rax, 1 - mov rdi, 1 - syscall -puts_str_newline_only: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret - -puts_print_int: - mov rax, [r12] - add r12, 8 - mov rbx, rax - mov r8, 0 - cmp rbx, 0 - jge puts_abs - neg rbx - mov r8, 1 -puts_abs: - lea rsi, [rel print_buf_end] - mov rcx, 0 - mov r10, 10 - cmp rbx, 0 - jne puts_digits - dec rsi - mov byte [rsi], '0' - inc rcx - jmp puts_sign -puts_digits: -puts_loop: - xor rdx, rdx - mov rax, rbx - div r10 - add dl, '0' - dec rsi - mov [rsi], dl - inc rcx - mov rbx, rax - test rbx, rbx - jne puts_loop -puts_sign: - cmp r8, 0 - je puts_finish_digits - dec rsi - mov byte [rsi], '-' - inc rcx -puts_finish_digits: - mov byte [rsi + rcx], 10 - inc rcx - mov rax, 1 - mov rdi, 1 - mov rdx, rcx - mov r9, rsi - mov rsi, r9 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 mov [r12], rax ret -word_write_buf: - mov rdx, [r12] ; len - mov rsi, [r12 + 8] ; addr - add r12, 16 ; pop len + addr - mov rax, 1 ; syscall: write - mov rdi, 1 ; fd = stdout - syscall - ret - ret word_drop: add r12, 8 ret @@ -399,6 +306,270 @@ word_rpick: sub r12, 8 mov [r12], rax ret +word_read_file: + ; stack: path_ptr (top), path_len (next) + mov rsi, [r12] ; path_ptr + mov rdx, [r12 + 8] ; path_len + add r12, 16 ; pop args + + ; open(path_ptr, O_RDONLY=0, mode=0) + mov rax, 2 ; syscall: open + mov rdi, rsi ; filename + xor rsi, rsi ; flags = O_RDONLY + xor rdx, rdx ; mode = 0 + syscall + mov r10, rax ; save open() result + cmp rax, 0 + jl .fail_open + mov r8, rax ; fd + + ; use lseek to determine file size: lseek(fd, 0, SEEK_END) + mov rax, 8 ; syscall: lseek + mov rdi, r8 ; fd + xor rsi, rsi ; offset = 0 + mov rdx, 2 ; SEEK_END + syscall + mov r11, rax ; save lseek() result + cmp rax, 0 + jl .close_fail_lseek + mov rsi, rax ; length = size + + ; mmap(NULL, size, PROT_READ=1, MAP_PRIVATE=2, fd, 0) + mov rax, 9 ; syscall: mmap + xor rdi, rdi ; addr = NULL + ; rsi already holds length + mov rdx, 1 ; PROT_READ + mov r10, 2 ; MAP_PRIVATE + mov r8, r8 ; fd + xor r9, r9 ; offset = 0 + syscall + mov rbx, rax ; addr + mov r12, r12 ; (no-op, for debug) + mov rax, 3 ; syscall: close + mov rdi, r8 ; fd + syscall + cmp rbx, -4095 + jae .fail_mmap + sub r12, 16 + mov [r12], rsi ; len (rsi held length across syscall) + mov [r12 + 8], rbx ; addr + ret + +.close_fail_lseek: + mov rax, 3 + mov rdi, r8 + syscall + mov rax, r11 ; return lseek() error code + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -1 + ret + +.fail_open: + mov rax, r10 ; return open() error code + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -2 + ret + +.fail_mmap: + mov rax, -1 ; return mmap() error + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -3 + ret + ret +word_write_file: + ; stack: path_ptr (top), path_len, buf_ptr, buf_len + mov rsi, [r12] ; path_ptr + mov rdx, [r12 + 8] ; path_len + mov r15, [r12 + 16] ; buf_ptr (save in callee-saved r15) + mov r13, [r12 + 24] ; buf_len (save in callee-saved r13) + add r12, 32 ; pop 4 args (we saved buf info) + + ; open(path_ptr, O_WRONLY|O_CREAT|O_TRUNC, 0666) + mov rdi, rsi ; filename + mov rsi, 577 ; flags = O_WRONLY|O_CREAT|O_TRUNC + mov rdx, 438 ; mode = 0o666 + mov rax, 2 ; syscall: open + syscall + cmp rax, 0 + jl .fail_open + mov r9, rax ; save fd + + ; write(fd, buf_ptr, buf_len) -- use preserved r15/r13 which survive syscalls + mov rax, 1 ; syscall: write + mov rdi, r9 ; fd + mov rsi, r15 ; buf_ptr + mov rdx, r13 ; buf_len + syscall + mov r10, rax ; save write result + cmp r10, 0 + jl .fail_write + + ; close(fd) + mov rax, 3 ; syscall: close + mov rdi, r9 + syscall + + sub r12, 8 + mov [r12], r10 + ret + +.fail_write: + mov rax, 3 + mov rdi, r9 + syscall + sub r12, 8 + mov [r12], r10 + ret + +.fail_open: + sub r12, 8 + mov [r12], rax + ret + ret +word_read_stdin: + ; stack: max_len + mov r14, [r12] ; max_len + add r12, 8 ; pop max_len + + ; mmap(NULL, max_len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) + mov rax, 9 ; syscall: mmap + xor rdi, rdi ; addr = NULL + mov rsi, r14 ; length + mov rdx, 3 ; PROT_READ|PROT_WRITE + mov r10, 34 ; MAP_PRIVATE|MAP_ANONYMOUS + mov r8, -1 ; fd = -1 + xor r9, r9 ; offset = 0 + syscall + cmp rax, -4095 + jae .fail_mmap + mov rbx, rax ; buffer addr + xor r9, r9 ; bytes_read = 0 + +.read_loop: + mov rax, 0 ; syscall: read + mov rdi, 0 ; fd = stdin + lea rsi, [rbx + r9] ; buf + offset + mov rdx, r14 + sub rdx, r9 ; remaining = max_len - bytes_read + syscall + cmp rax, 0 + je .done_read + js .read_error + add r9, rax + jl .read_loop + +.done_read: + ; push len (rcx) then addr (rbx) + cmp r9, r14 + je .done_no_null + mov byte [rbx + r9], 0 +.done_no_null: + sub r12, 16 + mov [r12], r9 + mov [r12 + 8], rbx + ret + +.read_error: + ; return negative errno in rax, addr = 0 + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], 0 + ret + +.fail_mmap: + sub r12, 16 + mov qword [r12], -1 + mov qword [r12 + 8], 0 + ret + ret +word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret +puts_print_int: + mov rax, [r12] + add r12, 8 + mov rbx, rax + mov r8, 0 + cmp rbx, 0 + jge puts_abs + neg rbx + mov r8, 1 +puts_abs: + lea rsi, [rel print_buf_end] + mov rcx, 0 + mov r10, 10 + cmp rbx, 0 + jne puts_digits + dec rsi + mov byte [rsi], '0' + inc rcx + jmp puts_sign +puts_digits: +puts_loop: + xor rdx, rdx + mov rax, rbx + div r10 + add dl, '0' + dec rsi + mov [rsi], dl + inc rcx + mov rbx, rax + test rbx, rbx + jne puts_loop +puts_sign: + cmp r8, 0 + je puts_finish_digits + dec rsi + mov byte [rsi], '-' + inc rcx +puts_finish_digits: + mov byte [rsi + rcx], 10 + inc rcx + mov rax, 1 + mov rdi, 1 + mov rdx, rcx + mov r9, rsi + mov rsi, r9 + syscall + ret +word_write_buf: + mov rdx, [r12] ; len + mov rsi, [r12 + 8] ; addr + add r12, 16 ; pop len + addr + mov rax, 1 ; syscall: write + mov rdi, 1 ; fd = stdout + syscall + ret + ret word_main: ; push str_0 sub r12, 8 diff --git a/build/a.o b/build/a.o index f77941fec56f1d898bc9e0df635340475bc8d704..9dda115f3cf0a5375299341caa6e030c4dd5a1ae 100644 GIT binary patch literal 5440 zcmbW5eQXp}5WwHj77InLDlv_g1k7n5(X$^It%7MA&|R}i|R9oRl{^fM;p^Ir|RJSTv}&@#LWF(&Uq)W8$R^7)P7 zD^Vln{%8zegRP&k;OdBEZD*ZYy-*#|^Aok2J2kQvXt)N67Tzy(w>nZRdUCzc7};5c z{S89T|5_WAQV-35e0`+0tRP1h?g!#FMsycM%AiCABT}!sOBC1L`y=(UggD5+(d#`S z%ps@tEt4~7AgCy(kTNjhISek&nxwEX(xBYfNCwbUgN&qJ2Qv+7c+dR@N)YH(cw90yX&>T}x6nfd6lfF;Pa)>eEU7b(1_h`IA;3Cf;5kL<*?B(;w zUh-vHK@~_jdi2YMR6z}B?sr=L#7Vs{7+IwkoX83ta~y+PeGJPZR)9s%Pc)6-9tziJ z?nHTkAkHYg|$I|Ev)?y1LX}JpfVa<;g8F4_;CFv{(h0cK^nlqMEwXJE1El_ zHJ{d+r(xf@2etfPBE0KK;JQ0Df?L^er$9c6s;E&!jlm6?J1KLgHJ3(l(|1UPm^&70 zK8*P+#@rJlc(A~5=x;w0I$0`ZJHb2HaFAc9@7kiTV7SMW2#$g&Sf3JHMZ^890-i&t zO^u?dx_oMs4PZ=@zgE4gK?)V7$Zn&Qs?m5H# zS!O`b|1AbDA=f?y1Uon8!rqtzp-e7RF-Aq>CB<-0k7D>8qgTLPS5B+ktdps@3v<+b zSRR81KtY+bI0#s|NSwViTmIwz~^a24xg^0>n6RipqdC^A(Y zkqN>yN~#JF42A@%ogOvmVAxT8X@PAeUqT-cOM!wp*iyL@IxLs7NGe|gc(QuwVt53+agXTkDZ@P~U0DWI z;8201`xFBd2(A{S2fgsxxW9io4wY3zDzDz8Wo1?jWNa&;K-5WYbwo4~cj6-2mCcH1 zwm0k8PP_|RkM^l2_3fk;SNdda{s;P2El!o@(x{sA3k%=lxDRJvRdc-I)$2JVRx$O} zvL6yHjJFbRXM7#;I~c!}_=Aiqy^z?<_GLgWW@~pqn)KUV7ECV*eSKbZeYteGjp?%njlTMo0 z4|o`mKuxA|mNiQ#EhKH*OK-rUbl4BAKj&lx-k{iRGo2i;QZQpCZ9S@Jznw}uCj6;x zyoXA4Pn*Q!*n1^wj$~wiEVY&;$C6?2xpnB~ux3a-wfXXqS9eH?oh se-6R*JmcQ~sXh#Fw11|g?0m`iS>g-n{Pp}9qz|Os#PMA9e1@j@7XsZd&Hw-a literal 4368 zcmbW4eTY<56u|GeyEdy^GlV%YO=J&ZfU+pvtXc1%eFe2FuYISTkvxGK?KoCJG=>yt~wpe32=ic)^_PD!$bm6^w z?(clud(XZ1eY~_K`S_wxNVp{=9ua=ar9yQ1BFSAMEb0UF|B2WaUW=J~*CGYRSr<`e zcNetLzmD-JDxfr}%Dc00;%?A{;o|#)5= z=;dF-0c|B23qy#g?lid$l^wCLR{mQI^(IGfWFk2t=bP-P4s|6vE)74VIp;O!D!OTh zChewC9Q)^Zi!_W&k0n0RMmA!Mvr6p^Npq^*aw1xJMhrJ<(^tBs51D_0KHX=Rz#R=r zOSRhN@x`rL?c6UdTHB=N{Gd<&aqv8V%ZFD0g>c%TE2SGcjN5LM#_Iu(*Wa@Qs=#QR zuXJZB>0FL9&`>BFdS!V`uh=RXzCD;#F~eZI8FijDBp&mmJ1sHY0hNj-5u{Y6Q*zze z5sTiTL?=uOopMpFhJ1I*Fg|(Jg^kJlgjp3Gp?%cY^MMis#(q?ii2-f z?!hp$pY#yy9yt;m*4kiWdL0Cm0R2FV8}5WQJu@F&9*6|nQ0u6EifbD=R>j=;y##f~ z7tp=AfbQ)DbSD?kz2)n)iaI;q>~UNUqzd+c=3LXtH-6VEL$NiuS61nm;~uz0dvJU7 zR3O{s3$3G#IKc+Zx!^4j%yR?ft1~vbRO%^Xos!e}ot=+EW07O$U|&a$orgnx5w1yX z^|$h<&Klobc8$KBhWat^9`m;tE?xOI*jQTx^ofs!F9O>e8bIZ2aD~72=HbK5-}sLb zsh+6E$EAWG;~a0EnyJ;QNLAUB&E*QK1`Ad$qd?rw?zcreld@AHo-P(eytt=mTXrf9 z(t&zGxLE`T*-X*!b1p!yuN zOgn3&OS@DvV}ZN0DD2BxN-7Sfh*6K+(@Lo zkgkw&1sar**hr*3W3*>nZJRH*_qhg?bfdj5pw0TSyB3DK6#f0~?D|W2PsT-5Ayawk zut4d^yAwCs-3(bEDr?K1?||v1!}7)cl$jU!9Yfm&7rIr*yMg;asM3KSbyAG#Wv{=Y%_EZ2t#&vi!>c diff --git a/build/hello.asm b/build/hello.asm index 2cc2435..9b91637 100644 --- a/build/hello.asm +++ b/build/hello.asm @@ -37,104 +37,11 @@ word_r_40: mov [r12], rax ret ret -word_strlen: - mov rax, [r12] ; addr - mov rcx, [r12 + 8] ; len - add r12, 16 ; pop len and addr - mov [r12], rcx ; push len - ret - ret -word_puts: - ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] - mov rax, [r12] ; len or int value - mov rbx, [r12 + 8] ; possible address - cmp rax, 0 - jl puts_print_int - lea r8, [rel data_start] - lea r9, [rel data_end] - cmp rbx, r8 - jl puts_print_int - cmp rbx, r9 - jge puts_print_int - ; treat as string: (addr below len) - mov rdx, rax ; len - mov rsi, rbx ; addr - add r12, 16 ; pop len + addr - test rdx, rdx - jz puts_str_newline_only - mov rax, 1 - mov rdi, 1 - syscall -puts_str_newline_only: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret - -puts_print_int: - mov rax, [r12] - add r12, 8 - mov rbx, rax - mov r8, 0 - cmp rbx, 0 - jge puts_abs - neg rbx - mov r8, 1 -puts_abs: - lea rsi, [rel print_buf_end] - mov rcx, 0 - mov r10, 10 - cmp rbx, 0 - jne puts_digits - dec rsi - mov byte [rsi], '0' - inc rcx - jmp puts_sign -puts_digits: -puts_loop: - xor rdx, rdx - mov rax, rbx - div r10 - add dl, '0' - dec rsi - mov [rsi], dl - inc rcx - mov rbx, rax - test rbx, rbx - jne puts_loop -puts_sign: - cmp r8, 0 - je puts_finish_digits - dec rsi - mov byte [rsi], '-' - inc rcx -puts_finish_digits: - mov byte [rsi + rcx], 10 - inc rcx - mov rax, 1 - mov rdi, 1 - mov rdx, rcx - mov r9, rsi - mov rsi, r9 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 mov [r12], rax ret -word_write_buf: - mov rdx, [r12] ; len - mov rsi, [r12 + 8] ; addr - add r12, 16 ; pop len + addr - mov rax, 1 ; syscall: write - mov rdi, 1 ; fd = stdout - syscall - ret - ret word_drop: add r12, 8 ret @@ -399,6 +306,270 @@ word_rpick: sub r12, 8 mov [r12], rax ret +word_read_file: + ; stack: path_ptr (top), path_len (next) + mov rsi, [r12] ; path_ptr + mov rdx, [r12 + 8] ; path_len + add r12, 16 ; pop args + + ; open(path_ptr, O_RDONLY=0, mode=0) + mov rax, 2 ; syscall: open + mov rdi, rsi ; filename + xor rsi, rsi ; flags = O_RDONLY + xor rdx, rdx ; mode = 0 + syscall + mov r10, rax ; save open() result + cmp rax, 0 + jl .fail_open + mov r8, rax ; fd + + ; use lseek to determine file size: lseek(fd, 0, SEEK_END) + mov rax, 8 ; syscall: lseek + mov rdi, r8 ; fd + xor rsi, rsi ; offset = 0 + mov rdx, 2 ; SEEK_END + syscall + mov r11, rax ; save lseek() result + cmp rax, 0 + jl .close_fail_lseek + mov rsi, rax ; length = size + + ; mmap(NULL, size, PROT_READ=1, MAP_PRIVATE=2, fd, 0) + mov rax, 9 ; syscall: mmap + xor rdi, rdi ; addr = NULL + ; rsi already holds length + mov rdx, 1 ; PROT_READ + mov r10, 2 ; MAP_PRIVATE + mov r8, r8 ; fd + xor r9, r9 ; offset = 0 + syscall + mov rbx, rax ; addr + mov r12, r12 ; (no-op, for debug) + mov rax, 3 ; syscall: close + mov rdi, r8 ; fd + syscall + cmp rbx, -4095 + jae .fail_mmap + sub r12, 16 + mov [r12], rsi ; len (rsi held length across syscall) + mov [r12 + 8], rbx ; addr + ret + +.close_fail_lseek: + mov rax, 3 + mov rdi, r8 + syscall + mov rax, r11 ; return lseek() error code + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -1 + ret + +.fail_open: + mov rax, r10 ; return open() error code + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -2 + ret + +.fail_mmap: + mov rax, -1 ; return mmap() error + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -3 + ret + ret +word_write_file: + ; stack: path_ptr (top), path_len, buf_ptr, buf_len + mov rsi, [r12] ; path_ptr + mov rdx, [r12 + 8] ; path_len + mov r15, [r12 + 16] ; buf_ptr (save in callee-saved r15) + mov r13, [r12 + 24] ; buf_len (save in callee-saved r13) + add r12, 32 ; pop 4 args (we saved buf info) + + ; open(path_ptr, O_WRONLY|O_CREAT|O_TRUNC, 0666) + mov rdi, rsi ; filename + mov rsi, 577 ; flags = O_WRONLY|O_CREAT|O_TRUNC + mov rdx, 438 ; mode = 0o666 + mov rax, 2 ; syscall: open + syscall + cmp rax, 0 + jl .fail_open + mov r9, rax ; save fd + + ; write(fd, buf_ptr, buf_len) -- use preserved r15/r13 which survive syscalls + mov rax, 1 ; syscall: write + mov rdi, r9 ; fd + mov rsi, r15 ; buf_ptr + mov rdx, r13 ; buf_len + syscall + mov r10, rax ; save write result + cmp r10, 0 + jl .fail_write + + ; close(fd) + mov rax, 3 ; syscall: close + mov rdi, r9 + syscall + + sub r12, 8 + mov [r12], r10 + ret + +.fail_write: + mov rax, 3 + mov rdi, r9 + syscall + sub r12, 8 + mov [r12], r10 + ret + +.fail_open: + sub r12, 8 + mov [r12], rax + ret + ret +word_read_stdin: + ; stack: max_len + mov r14, [r12] ; max_len + add r12, 8 ; pop max_len + + ; mmap(NULL, max_len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) + mov rax, 9 ; syscall: mmap + xor rdi, rdi ; addr = NULL + mov rsi, r14 ; length + mov rdx, 3 ; PROT_READ|PROT_WRITE + mov r10, 34 ; MAP_PRIVATE|MAP_ANONYMOUS + mov r8, -1 ; fd = -1 + xor r9, r9 ; offset = 0 + syscall + cmp rax, -4095 + jae .fail_mmap + mov rbx, rax ; buffer addr + xor r9, r9 ; bytes_read = 0 + +.read_loop: + mov rax, 0 ; syscall: read + mov rdi, 0 ; fd = stdin + lea rsi, [rbx + r9] ; buf + offset + mov rdx, r14 + sub rdx, r9 ; remaining = max_len - bytes_read + syscall + cmp rax, 0 + je .done_read + js .read_error + add r9, rax + jl .read_loop + +.done_read: + ; push len (rcx) then addr (rbx) + cmp r9, r14 + je .done_no_null + mov byte [rbx + r9], 0 +.done_no_null: + sub r12, 16 + mov [r12], r9 + mov [r12 + 8], rbx + ret + +.read_error: + ; return negative errno in rax, addr = 0 + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], 0 + ret + +.fail_mmap: + sub r12, 16 + mov qword [r12], -1 + mov qword [r12 + 8], 0 + ret + ret +word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret +puts_print_int: + mov rax, [r12] + add r12, 8 + mov rbx, rax + mov r8, 0 + cmp rbx, 0 + jge puts_abs + neg rbx + mov r8, 1 +puts_abs: + lea rsi, [rel print_buf_end] + mov rcx, 0 + mov r10, 10 + cmp rbx, 0 + jne puts_digits + dec rsi + mov byte [rsi], '0' + inc rcx + jmp puts_sign +puts_digits: +puts_loop: + xor rdx, rdx + mov rax, rbx + div r10 + add dl, '0' + dec rsi + mov [rsi], dl + inc rcx + mov rbx, rax + test rbx, rbx + jne puts_loop +puts_sign: + cmp r8, 0 + je puts_finish_digits + dec rsi + mov byte [rsi], '-' + inc rcx +puts_finish_digits: + mov byte [rsi + rcx], 10 + inc rcx + mov rax, 1 + mov rdi, 1 + mov rdx, rcx + mov r9, rsi + mov rsi, r9 + syscall + ret +word_write_buf: + mov rdx, [r12] ; len + mov rsi, [r12 + 8] ; addr + add r12, 16 ; pop len + addr + mov rax, 1 ; syscall: write + mov rdi, 1 ; fd = stdout + syscall + ret + ret word_main: ; push str_0 sub r12, 8 diff --git a/build/hello.o b/build/hello.o index e3e581a8c77bba264915674ad4e8e8b4e7201808..2a1766a33e8d7a8df616c4c7c4235002cbc8fc26 100644 GIT binary patch literal 5456 zcmbW4e`p+a7Qnx2k~aOJyQlRi60yoE6?AQW$QiAYlvZYRR(e=Lv^s9G8?$w?8)j!s z#i-R-bX@&wTKpqB3L=kAJ7&tVq@3$-uKPU zh6XPSK|<&)g+7jN5d2uP1}g=Z9-j$vRF&h^GCgpIVn^7Hod4{F#-c8d{}Yc39x}Hr zAecLY*6iZ({TLuzn1-9+$6=|}2;oY?Z=UbKUS&r=7D74yWuPl_0!Tf*3hzoy&|Rq} zc;Z+&zcqR>YNY-DS)-R@>+2G@I!3H>)@wE^jY)H4vf1#b$JPUlHz6_NuPf7UOjfIb z+^n=DA8)|^CS{I%*Bq5{56yslW3sufK%*;Lf%q*+(+80@NT^~Z6Q;jXbJO3NOw1GF zAPYxt41_QTO&wZhXV5@Yk)|LS7zrE(7w1h<*^*qX-Ppng(9~**Bw>P?)p~f;3@6Qu zL5j!|bnDV+XXY|+odAvlDQ5Mr#>~mZ=&Fb%$hFZ~eG?ZczN?D43ulSSo;!`~Z>N#% zK8@_f)5!iF%8ZIGkb3m!mk+6e8Zi7XjFF?q%*t?bty%GsYfQ{>8g7X+mPfh*i#{^B zZVdNOyvgt<>k9;Nc5uGdC&yOkg4B6jPn?T%Za#KS#CPp6b{>iE+6$F?0Dgyz3qQg| z{cXKvp`L+uCSdeLSYo(zBi}<|ZBk$hYkyy)yrBb>qQMn@uO3GTH@+Y47YYv202U?_ zV|c6>{*2N3qtSW@_MN}i82L%XpL_(k=}(N|R<`_UkdLD(YE)5Uc$48zQSOY^+Bk0d zZc<456Y16in9pk3KRSj73k-+;!zW|MYPHe^@D4T{Cr~&?@Cync3t$&ROT((eGCR0!Cf7iGZ*_zBEmXJ!9y* z<$qxLr!4;)%78iYvl>2!UHbqK?A){udt(8FGFqr=nu{h#isk<}j^THYUj%nkJFRnb zEv4dS%u(wBItJec6?MaC#|q0oVO{!;_Rm|o{d_aFXZW*p=W(xT!&Ku6T*XA1jw{UG zoD`r1O{N=@lpstaQC)y|7*W_aTcdbVD{B;AY|84a4tH6d?>=yi0juwSj&)(|JmjsU z)Vz)Pi8oErh~*(NMz6%dwDj>NJp;ZIK?$XMc2t{kn(cdJ(bF4 zyo^fqlu9a9>Mwb&m+67leFOT*eK+T1v_4x~{DHnTs^hhVG#VEC!ov4B?!)<4!vb%3 z{r-=swL+cV!C=2laQz(;Q(c00Q$MCQ3w|T>I|bju{2sxzUQ7)N-p~3E3hpw0M)3QY z|4Z=4n7=Fd)65SG{sQwK1b>P7S-3!v>)+IlsdEG$XMVNd`sx~FVt$9n}!Ea;!mEhZ$pHD9jDn7bB%DhYP z7n$E6_?ygc75o$C+XO$x{9(a=W?mIMLHUiTF9pAVd4u?Wsp})AE)l$g^(DWK`39kH zF#ogQw=*vYzKyvrxJR6V3zH13hZf;Gi65`wt1o&z#rpF9@L!12Evl||*EtnfUG~Z% z{6BR**Vq3p!l#(a|JQ$jnG%b#3Uz8kwNc7c{QqMtjz7&jzqHY`6CY3LLK8-W!qT!gi1aJ4nL7 zKoH$PxlnIo`n1VRfhR0-ItoGHc6*Q^7n)kz4dWfm2kCGl&0HpH_vM{HJ?N%-onk3x z_hs^q?UZskPNZ9xlcYG9EATvX1z`|FZr%es^%=r`icC;n+mIq*z2s%{(b=e#3DHyhBjFCN(ygK?5rMW?2x%mp}*flT1HF>f=R zf1RSc?ZA?dC49{t{=7sS#mYe4b&15q#y$@)tDyoteY+ zx%4cb>!^=oXYub5TrUVt|CT_$FT&CO$(pwFso=BBm+*NU_%qBOOwTaKb2ji9n(9~Q C)ib>S literal 4384 zcmbW4Z)hAv6u@Vjq+a^RJEfFh^C7|&T4}H8rKLoRB-+X@y`a#jUuw6P+_gD+xr=*y zO{xi2&X#V^P?0K>`Ugb84@E1Y#QMQB7ZYk~!3rW4L~PN5Rjfr*NaTEP=Ix)pCi&pN z?!5WEKQr@Yc6RrL?TN=0X_|10CLR`k%cVlJ`69_}A|z@9^#6(27ha2*d)p!fCRi5{ zW_K5~(Z7cA2r8f~QDsFhZbY)ySvzEuYokVKJfu65BU^!n>yYT-Ple&sMk^IpZB zalSH~8wuxPxQ>QG*)Ym0qDI+P$?)yLtb!Q^<87$(tReB3C&Ous8V;ybG>IUkGM$ne z&aP>fE19M;-kV|pC~lmPueiyQ8wK0PxZT@i=`+fZ+#_YqdXX0gL|dPz#MnLEz*J8 zqoWMjE{!*j)Z+x}bZ6XKAeiSS%GcKD$Wp1NjBS;ip5NQ^adasL#W7 zNx%Oa`KaDDzPaq`eLEfXqu@R2Z!uiD((kabwhQPJkA*J-+Z!4{Ef0FSX#QPZUBtFFWGsKTEzL)qZ#`DBKVtj!3B;zj;zry${ z#H);}_0YsB_9(qW_FEYLfcQ?vph3gg#_-(>u6 z;;Z1RELi>}{wU*%WnMJ#6yp)%`xw8E_yFUpi4QTpfjE982FruQ-)DTATT%DfF0R zCI^)&_NhMmt&E*EyNY{NGi8Chw8$SwTS_YQCy7~kTOl(Jh9u`Qq_vCP`;|KGg-1J5 z$Ne~QKe!q1@W_&Y|mXz6&a`i8J0>5Qw+u%Ys3wbwjA4pXi zx=g{g0)JJRHYCwfL{*Zg{eWxdNhbORi~D5ZcE?A1mcDrC_f&q-D6aN=iJZ|MeP^qx m9An)55B(&-G0sd?#hGM$miRx657IZ)8FYq%=Y~6GZ2t$}v;K=0 and next is a pointer in [data_start, data_end] - mov rax, [r12] ; len or int value - mov rbx, [r12 + 8] ; possible address - cmp rax, 0 - jl puts_print_int - lea r8, [rel data_start] - lea r9, [rel data_end] - cmp rbx, r8 - jl puts_print_int - cmp rbx, r9 - jge puts_print_int - ; treat as string: (addr below len) - mov rdx, rax ; len - mov rsi, rbx ; addr - add r12, 16 ; pop len + addr - test rdx, rdx - jz puts_str_newline_only - mov rax, 1 - mov rdi, 1 - syscall -puts_str_newline_only: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret - -puts_print_int: - mov rax, [r12] - add r12, 8 - mov rbx, rax - mov r8, 0 - cmp rbx, 0 - jge puts_abs - neg rbx - mov r8, 1 -puts_abs: - lea rsi, [rel print_buf_end] - mov rcx, 0 - mov r10, 10 - cmp rbx, 0 - jne puts_digits - dec rsi - mov byte [rsi], '0' - inc rcx - jmp puts_sign -puts_digits: -puts_loop: - xor rdx, rdx - mov rax, rbx - div r10 - add dl, '0' - dec rsi - mov [rsi], dl - inc rcx - mov rbx, rax - test rbx, rbx - jne puts_loop -puts_sign: - cmp r8, 0 - je puts_finish_digits - dec rsi - mov byte [rsi], '-' - inc rcx -puts_finish_digits: - mov byte [rsi + rcx], 10 - inc rcx - mov rax, 1 - mov rdi, 1 - mov rdx, rcx - mov r9, rsi - mov rsi, r9 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 mov [r12], rax ret -word_write_buf: - mov rdx, [r12] ; len - mov rsi, [r12 + 8] ; addr - add r12, 16 ; pop len + addr - mov rax, 1 ; syscall: write - mov rdi, 1 ; fd = stdout - syscall - ret - ret word_drop: add r12, 8 ret @@ -399,6 +306,270 @@ word_rpick: sub r12, 8 mov [r12], rax ret +word_read_file: + ; stack: path_ptr (top), path_len (next) + mov rsi, [r12] ; path_ptr + mov rdx, [r12 + 8] ; path_len + add r12, 16 ; pop args + + ; open(path_ptr, O_RDONLY=0, mode=0) + mov rax, 2 ; syscall: open + mov rdi, rsi ; filename + xor rsi, rsi ; flags = O_RDONLY + xor rdx, rdx ; mode = 0 + syscall + mov r10, rax ; save open() result + cmp rax, 0 + jl .fail_open + mov r8, rax ; fd + + ; use lseek to determine file size: lseek(fd, 0, SEEK_END) + mov rax, 8 ; syscall: lseek + mov rdi, r8 ; fd + xor rsi, rsi ; offset = 0 + mov rdx, 2 ; SEEK_END + syscall + mov r11, rax ; save lseek() result + cmp rax, 0 + jl .close_fail_lseek + mov rsi, rax ; length = size + + ; mmap(NULL, size, PROT_READ=1, MAP_PRIVATE=2, fd, 0) + mov rax, 9 ; syscall: mmap + xor rdi, rdi ; addr = NULL + ; rsi already holds length + mov rdx, 1 ; PROT_READ + mov r10, 2 ; MAP_PRIVATE + mov r8, r8 ; fd + xor r9, r9 ; offset = 0 + syscall + mov rbx, rax ; addr + mov r12, r12 ; (no-op, for debug) + mov rax, 3 ; syscall: close + mov rdi, r8 ; fd + syscall + cmp rbx, -4095 + jae .fail_mmap + sub r12, 16 + mov [r12], rsi ; len (rsi held length across syscall) + mov [r12 + 8], rbx ; addr + ret + +.close_fail_lseek: + mov rax, 3 + mov rdi, r8 + syscall + mov rax, r11 ; return lseek() error code + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -1 + ret + +.fail_open: + mov rax, r10 ; return open() error code + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -2 + ret + +.fail_mmap: + mov rax, -1 ; return mmap() error + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], -3 + ret + ret +word_write_file: + ; stack: path_ptr (top), path_len, buf_ptr, buf_len + mov rsi, [r12] ; path_ptr + mov rdx, [r12 + 8] ; path_len + mov r15, [r12 + 16] ; buf_ptr (save in callee-saved r15) + mov r13, [r12 + 24] ; buf_len (save in callee-saved r13) + add r12, 32 ; pop 4 args (we saved buf info) + + ; open(path_ptr, O_WRONLY|O_CREAT|O_TRUNC, 0666) + mov rdi, rsi ; filename + mov rsi, 577 ; flags = O_WRONLY|O_CREAT|O_TRUNC + mov rdx, 438 ; mode = 0o666 + mov rax, 2 ; syscall: open + syscall + cmp rax, 0 + jl .fail_open + mov r9, rax ; save fd + + ; write(fd, buf_ptr, buf_len) -- use preserved r15/r13 which survive syscalls + mov rax, 1 ; syscall: write + mov rdi, r9 ; fd + mov rsi, r15 ; buf_ptr + mov rdx, r13 ; buf_len + syscall + mov r10, rax ; save write result + cmp r10, 0 + jl .fail_write + + ; close(fd) + mov rax, 3 ; syscall: close + mov rdi, r9 + syscall + + sub r12, 8 + mov [r12], r10 + ret + +.fail_write: + mov rax, 3 + mov rdi, r9 + syscall + sub r12, 8 + mov [r12], r10 + ret + +.fail_open: + sub r12, 8 + mov [r12], rax + ret + ret +word_read_stdin: + ; stack: max_len + mov r14, [r12] ; max_len + add r12, 8 ; pop max_len + + ; mmap(NULL, max_len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) + mov rax, 9 ; syscall: mmap + xor rdi, rdi ; addr = NULL + mov rsi, r14 ; length + mov rdx, 3 ; PROT_READ|PROT_WRITE + mov r10, 34 ; MAP_PRIVATE|MAP_ANONYMOUS + mov r8, -1 ; fd = -1 + xor r9, r9 ; offset = 0 + syscall + cmp rax, -4095 + jae .fail_mmap + mov rbx, rax ; buffer addr + xor r9, r9 ; bytes_read = 0 + +.read_loop: + mov rax, 0 ; syscall: read + mov rdi, 0 ; fd = stdin + lea rsi, [rbx + r9] ; buf + offset + mov rdx, r14 + sub rdx, r9 ; remaining = max_len - bytes_read + syscall + cmp rax, 0 + je .done_read + js .read_error + add r9, rax + jl .read_loop + +.done_read: + ; push len (rcx) then addr (rbx) + cmp r9, r14 + je .done_no_null + mov byte [rbx + r9], 0 +.done_no_null: + sub r12, 16 + mov [r12], r9 + mov [r12 + 8], rbx + ret + +.read_error: + ; return negative errno in rax, addr = 0 + sub r12, 16 + mov [r12], rax + mov qword [r12 + 8], 0 + ret + +.fail_mmap: + sub r12, 16 + mov qword [r12], -1 + mov qword [r12 + 8], 0 + ret + ret +word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret +puts_print_int: + mov rax, [r12] + add r12, 8 + mov rbx, rax + mov r8, 0 + cmp rbx, 0 + jge puts_abs + neg rbx + mov r8, 1 +puts_abs: + lea rsi, [rel print_buf_end] + mov rcx, 0 + mov r10, 10 + cmp rbx, 0 + jne puts_digits + dec rsi + mov byte [rsi], '0' + inc rcx + jmp puts_sign +puts_digits: +puts_loop: + xor rdx, rdx + mov rax, rbx + div r10 + add dl, '0' + dec rsi + mov [rsi], dl + inc rcx + mov rbx, rax + test rbx, rbx + jne puts_loop +puts_sign: + cmp r8, 0 + je puts_finish_digits + dec rsi + mov byte [rsi], '-' + inc rcx +puts_finish_digits: + mov byte [rsi + rcx], 10 + inc rcx + mov rax, 1 + mov rdi, 1 + mov rdx, rcx + mov r9, rsi + mov rsi, r9 + syscall + ret +word_write_buf: + mov rdx, [r12] ; len + mov rsi, [r12 + 8] ; addr + add r12, 16 ; pop len + addr + mov rax, 1 ; syscall: write + mov rdi, 1 ; fd = stdout + syscall + ret + ret word_main: ; push 2 sub r12, 8 diff --git a/build/main.o b/build/main.o index e49159b0685dca0cdb0d7deb0edba54a45e24a0d..9008a990bf076b7c270fd49608be4717f8ad25d8 100644 GIT binary patch literal 5488 zcmbW4eT-aF6u|G;-P&z28*OMfD~ zeymRnKA0z2=S&Ee0B{L!yP>7P?y-DHc7wUTBIuT!Z6Iq33_8 z4{B+IVL-n$QeQEU-i4Jw+@^@`f=UIHs9;1Ib@v#>b$4Z?af%Y14D?>=DPaydwI7+1 z!2m%+Ifc|g5HDd!amplx6_NQWjTICCL(P{fY1ARieB~YtLq*d=P$HQLrgctmFmW!V zE&=+17OVP9Pf^L(q(+a9V zDyzr5TqqUvfaZRy<@fE^3j>h_dcldDrelp`@YNW@_J|c=)AOSXhwu!A>oj+?vO%!U zMO3fFk)b)NAypk0OHNH%U5^bT;f-6h4ST~Iw?XIbfX{C2^iOe9|J$y?x6?4r2zZb9 zErwf{{}mdmQ$Q^2{r3ay4FjNZHMqk&E9>y#(vSS}A{Pf`fC!_FL-<(H+zGAuPpx@3 zoI7`$mj6qHA9(<{?v4!MQ8wIh&<~?2S`^V@pi^_lWbL%(@-QCy4rvf`M`F!8u%5-3 zyKe{|EZ`2~`zJ&D%jN76$PNx1)ED}@zUUhm?jEIrN5MGkPZ_SF;eJvD4s6o#bDQAn^SmfMo)wFZRvpQhu?-g<%%I6T*DIG-8zK18}7%3d)RP)k`>VN z|A>LPl-kFD;N-?!I2+R-)X9x1#;9q$q8RRVUx+P<^b8r_MWAbr@)vGE2Mo?tDHX;jz zWt3DkAU=%bvX>i!_@oxbApWokqpdj5ZnS-P&!rmdzWX)yg|=b0bBrv_dsv@v-I(;4 z?IUgQ0(6#JAFfj~K%c^zI^>G9{G_<2L7UjyA$`dF9rWoKo(-Jj+T&)!Es%}-f$knK++8x2dC&z8 zH8`eEYk&s9-GcI9D|_++kV~)sQ!bZ2hxYO)x_L5Mm+&{d^j5$E#-dnSc@P|LfG^J& zap{2oz(}P#(QFw`5<^LYuOeE~6?Ky991%^#ow$g0WwRohU6XZeC*B3pUA^i~V>_9O zD|^p-#yd`3D-M*WGpL#N4G!NEaJf^jnrYr3PLyULfh7!H_`ZN|0xdxZ@`Z97677tu zaY$Ut_%b;TiQ5=oPW%qWZzbNx_-f+!GJYrV#~Hty_-l+mNc=;_A0@tr@n?wt!T3wW zkHZZLTx!0Mn9I04HBiq>7$23sA#pw99}(|j{Bzu zgB*v%KE{tH&Rgze;!Ug-&nA8`#G9Z!VC}jf{Ur_O~j(Z zJ|MYVv|oIX9-4taCb|5ovVXe5Wg}H|FV4VUsqpH#-%^_`%JVu1ZKxhZ|Xt5+c#L}hLJ z>+Q3=a@YYe8Bdr!R?0K?hSBa+CYv;S;#SH`Ws^xNq+QWVO{OoIrg^Fr{v!Hq%YitR z8T@fnhLB?wgR5Bdtdp>Uv&nH(W|Yc!n<|G&lgOl#CXNFc1~kx<>0Bx`MJXdBZQCnv zAfimzUs_+z$qM{}X1C3BvOi_PjG1)mE=BunEA5!@QNwr_StqR3mggxmS23*BX=T`B zrLF85lg#94QKjk1Q3K*JQ;GLvG6LU$>AXoX2_2Gv^9S3lZl(j}u@zA_NmPCqv?7`4 zi|vI|F||z%l-0S;hH+@q@%?(R0+x JXMnu`{R=O^X|@0W literal 4416 zcmbW4eTY<56u|FucWqX!S;B0?g$gE6&~2U7WJzilKX^}OAy~8i5TCO<<2pDW+nYD8 z(ryXUhRI3xui8vSj7BctF1q!Tdn5}4< zJrsAr82#%QKZuGNjj#A_unEC$F8_mq7DBQ3{P))IMN@bF_2lPvJhv^Nm_38C9H;fS zQDU&`f*-CGTeIp!1bV)9RNcajK|8^M^Z8eS4bKVsy+Rv3g#&1K4Cu?}kBvTp>Tc)P z*yw7MDz8GgG08e+?2u8aj~K;sA>ElA+W<7&fJ6^}CJd)OQZBoCqtp^PREOiu!YKY0 z3TR8QNC-kS8O{>dp|m3s(u;qIp`O^NERfi!+;6O-Jk%NMxHSB@?o8;;kLae4T(Oso z;o85zOSs{@^jPF0eRLhJ_l#0|OVXWkm)wY6oEF24`qb4f=|kqH(WmRoBDkVKVX
XfOXrA(s(uC^Y!;Ef-bNc=c3`< zjyadZ4YU->hEZA?F-o>dhHnpMWy~-bZ$h1C4T;A*8BR;Ya6qM^NdzgC>6F}Xc0`)~ zqeLf6Jb024=8&f%k4%Q4xiCP`(APl_Z#{4ne3H_(NHd5tkO9PRh4E2uk=Xkc^V`a>pKTA;e+B~`w z^XT50NB8zTy0?6tUQ+jtw|iWd1F3=<(4C+3;`LibX(+M+YvmyWbKDJ=rfw{c?h<6X zc&=@%5jWVNJLkLuf_<)~d~Jw~EtY!9*apez{+*qVk@4`cvryOJV-s*wUx42g{o!xq ztvYLcwd@*wJ011o;63h_7#>~mCKT3Y0dwMG;mbgI!vLt<4W95<-adS|>1+Q{BGr@i z5quoF@(PeE@BdS+R!&Y=t1iW-fGeYQ1t0O1k$?q^MY-~96&!ou;u<5aybu5wsggmn zEjWpR(k8f+(b8?Lc5=ThS`%?QE?Rr@dC{8RleaB9-V4%!jOuA@CDUgALy&_@;;kA;^!(u_ihhS7S{)#rRe^*2GT6 zw-bMk@m<6}VSFF)Zy6sUeuwcR#Ft?L1MLkdYl8Flh)0?IN5s1rKTCWk;}?nVW&8)? zFEf6Pc!}|w#E&yRMf?NCRVirV0^>{MSQEc6ejo8Wj6X;`%t~k_@s*6PCEm*Tlf<89 zd@Jz*#(RhlGroiPVaAih-();X{A0!kiBB?KBz}$Yqr|I>zfOEP`&fII_CB}ayevR=P#P2Zv2l3_XBXWlLM#dXtUNo_taaA{(=x6)^ zvft0Re2_!&4l}OmNfY=L8f+aD=M>``iT}-bOmcY%h7r%q!FNf{k^`Ro9+wI6Vp((W z10I)xXaCY1{0Q+{|5KW3J?DE1sdVDeOgxosjpsAM%-eCxrmi)cGn4yMwz)5!E+oZZ z&Ptel=Grz_imp+T{i2s1@6)!w=ZcaDL)t| zX60;!%qSR=oK2C|F7)kH>ZlhU?MNN<<3#=7X0+D}=?ZaIphcO{bwt_|W_!ZbuJPse zKG%SfZnpOYv`Jrf&%$(%B9n1!2D9hcsoWO4usvjvPVXg$!6F92Qv>|(zBC3-_6#^cbCz8gq|$@mQMKN%mAo&=%$7xex$l>h($ diff --git a/main.py b/main.py index b8580c3..25b4950 100644 --- a/main.py +++ b/main.py @@ -476,7 +476,6 @@ class Parser: def _execute_immediate_word(self, word: Word) -> None: try: - print(f"[ct] invoking {word.name}") self.compile_time_vm.invoke(word) except ParseError: raise @@ -1075,7 +1074,6 @@ class CompileTimeVM: word = self.dictionary.lookup(name) if word is None: raise ParseError(f"unknown word '{name}' during compile-time execution") - print(f"[ct-call] {name} stack={self.stack}") self._call_word(word) def _execute_nodes(self, nodes: Sequence[ASTNode]) -> None: @@ -2294,6 +2292,7 @@ class Compiler: self.parser = Parser(self.dictionary, self.reader) self.assembler = Assembler(self.dictionary) + def compile_source(self, source: str) -> Emission: tokens = self.reader.tokenize(source) module = self.parser.parse(tokens, source) @@ -2328,12 +2327,19 @@ class Compiler: return "\n".join(lines) + "\n" -def run_nasm(asm_path: Path, obj_path: Path) -> None: - subprocess.run(["nasm", "-f", "elf64", "-o", str(obj_path), str(asm_path)], check=True) +def run_nasm(asm_path: Path, obj_path: Path, debug: bool = False) -> None: + cmd = ["nasm", "-f", "elf64"] + if debug: + cmd.append("-g") + cmd += ["-o", str(obj_path), str(asm_path)] + subprocess.run(cmd, check=True) -def run_linker(obj_path: Path, exe_path: Path) -> None: - subprocess.run(["ld", "-o", str(exe_path), str(obj_path)], check=True) +def run_linker(obj_path: Path, exe_path: Path, debug: bool = False) -> None: + cmd = ["ld", "-o", str(exe_path), str(obj_path)] + if debug: + cmd.append("-g") + subprocess.run(cmd, check=True) def cli(argv: Sequence[str]) -> int: @@ -2342,6 +2348,8 @@ def cli(argv: Sequence[str]) -> int: parser.add_argument("-o", dest="output", type=Path, default=Path("a.out")) parser.add_argument("--emit-asm", action="store_true", help="stop after generating asm") parser.add_argument("--temp-dir", type=Path, default=Path("build")) + parser.add_argument("--debug", action="store_true", help="compile with debug info") + args = parser.parse_args(argv) compiler = Compiler() @@ -2356,8 +2364,8 @@ def cli(argv: Sequence[str]) -> int: print(f"[info] wrote {asm_path}") return 0 - run_nasm(asm_path, obj_path) - run_linker(obj_path, args.output) + run_nasm(asm_path, obj_path, debug=args.debug) + run_linker(obj_path, args.output, debug=args.debug) print(f"[info] built {args.output}") return 0