ref: 5b2e3e6495320fa7ce29823d72c27de3194befd4
parent: 5341650a679df5560143a08abecb546b07448c4e
author: Ori Bernstein <[email protected]>
date: Mon Aug 26 14:20:41 EDT 2013
Initialize environment variables on Linux.
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -4,6 +4,7 @@
blat.myr \
chartype.myr \
die.myr \
+ env.myr \
error.myr \
extremum.myr \
fmt.myr \
--- a/libstd/start-linux.s
+++ b/libstd/start-linux.s
@@ -1,6 +1,17 @@
+.data
+/* std._environment : byte[:][:] */
+.globl std$_environment
+std$_environment:
+.envbase:
+.quad 0 /* env size */
+.envlen:
+.quad 0 /* env ptr */
+
+.text
/*
* counts the length of the string pointed to
- * by %rbx, returning len in %r9
+ * by %r8, returning len in %r9. Does not modify
+ * any registers outside of %r9
*/
cstrlen:
xorq %r9,%r9
@@ -13,36 +24,74 @@
jne .lenloop
ret
+
+/*
+ * Counts the size of the null terminated string vector
+ * pointed to by %rbx. Clobbers %r10,%r11
+ */
+count:
+ xorq %r9,%r9
+ movq %rbx,%r11
+.countloop:
+ movq (%r11),%r10
+ testq %r10,%r10
+ jz .countdone
+ addq $1,%r9
+ addq $8,%r11
+ jmp .countloop
+.countdone:
+ ret
+
+/*
+ * iterate over the strings for argc, and put
+ * them into the args array.
+ *
+ * argc in %rax, argv in %rbx, dest vector in %rcx
+ */
+cvt:
+ jmp .cvttest
+.cvtloop:
+ subq $1,%rax
+ movq (%rbx),%r8
+ call cstrlen
+ movq %r8, (%rcx)
+ movq %r9, 8(%rcx)
+ addq $8, %rbx
+ addq $16, %rcx
+.cvttest:
+ testq %rax,%rax
+ jnz .cvtloop
+.cvtdone:
+ ret
+
.globl _start
_start:
/* turn args into a slice */
movq %rsp,%rbp
- /* stack allocate sizeof(byte[:])*argc */
+ /* stack allocate sizeof(byte[:])*(argc + len(envp)) */
movq (%rbp),%rax
+ leaq 16(%rbp,%rax,8), %rbx /* envp = argv + 8*argc + 8 */
+ call count
+ addq %r9,%rax
imulq $16,%rax
subq %rax,%rsp
movq %rsp, %rdx /* saved args[:] */
- /* iterate over the strings for argc, and put
- * them into the args array. */
+ /* convert envp to byte[:][:] for std._environment */
+ movq (%rbp),%rax
+ leaq 16(%rbp,%rax,8), %rbx /* envp = argv + 8*argc + 8 */
+ movq %r9,%rax
+ movq %rsp, %rcx
+ movq %r9,.envlen
+ movq %rdx,.envbase
+ call cvt
+ movq %rcx,%rdx
+
+ /* convert argc, argv to byte[:][:] for args. */
movq (%rbp), %rax /* argc */
leaq 8(%rbp), %rbx /* argv */
- movq %rsp, %rcx
movq (%rbp), %rsi /* saved argc */
-
- testq %rax,%rax
- jz .cvtdone
- .cvtloop:
- subq $1,%rax
- movq (%rbx),%r8
- call cstrlen
- movq %r8, (%rcx)
- movq %r9, 8(%rcx)
- addq $8, %rbx
- addq $16, %rcx
- testq %rax,%rax
- jnz .cvtloop
- .cvtdone:
+ call cvt
pushq %rsi
pushq %rdx
--- a/libstd/test.myr
+++ b/libstd/test.myr
@@ -19,6 +19,10 @@
std.put("option %c, arg = %s\n", o, a)
;;
+ std.put("env.len = %i\n", std._environment.len)
+ for i = 0; i < std._environment.len; i++
+ std.put("env[%i] = %s\n", i, std._environment[i])
+ ;;
std.put("args.len = %i\n", args.len)
for i = 0; i < args.len; i++
std.put("args[%i] = %s\n", i, args[i])