Skip to content

Instantly share code, notes, and snippets.

@cho45
Created March 14, 2014 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cho45/9549157 to your computer and use it in GitHub Desktop.
Save cho45/9549157 to your computer and use it in GitHub Desktop.
/*#!as --gstabs+ -o sketch.o sketch.s && ld -o sketch -e _start sketch.o && objdump -d -j .text -j .data sketch && ./sketch
*/
.global _start
.macro sys_exit
mov r7, $0x01 /* set system call number to 1 (exit) */
svc $0x00 /* supervisor call */
.endm
.macro sys_write
mov r7, $0x04
svc $0x00 /* supervisor call */
.endm
_start:
mov lr, #0
/* r0 = argc */
ldr r0, [sp]
/* r1 = argv */
add r1, sp, $0x04
/* r2 = argc * 4 (skip argv) */
mov r3, $0x04
mul r2, r0, r3
/* r2 += 4 (skip null word) */
add r2, r2, $0x04
/* r2 += offset (ok this is environ) */
add r2, r1
/* save char** environ to global variable */
ldr r3, =environ
str r2, [r3]
/* r0 = argc, r1 = argv, r2 = environ */
bl main
/* not reached */
mov r0, $0xff
sys_exit
main:
/* getenv("USER") */
adr r0, USER
bl getenv
/* if "USER" is not in ENV */
cmp r0, $0x00
bleq error
bl puts
mov r0, $0x00 /* set exit status to 0 */
sys_exit
USER:
.asciz "USER"
.align 2
error:
mov r0, $0x01
sys_exit
strncmp: /* char* s1, char* s2, size_t len -> 1|0 */
stmfd sp!, {v1-v5, lr} /* save variable resistors and returning address */
mov r3, $0x00 /* result */
1: cmp r2, $0x00
beq 2f /* if (r2 == 0) goto 2 */
sub r2, r2, $0x01 /* len-- */
ldrb r4, [r0], $0x01 /* r4 = *s1++ */
ldrb r5, [r1], $0x01 /* r5 = *s2++ */
cmp r4, r5
beq 1b /* if (r4 == r5) goto 1 */
add r3, $0x01 /* r3++ (this function always returns 1 when the comparing fails) */
2:
mov r0, r3
ldmfd sp!, {v1-v5, pc} /* restore variable resistors and set pc to returning address */
strlen: /* char* str* -> uint */
mov r1, $0x00 /* r1 = result */
/* r2 = *str++ (ldrb = load byte, and r0 increment after) */
1: ldrb r2, [r0], $0x01
cmp r2, $0x00
addne r1, r1, $0x01 /* if (r2 != 0) r1++ */
bne 1b /* if (r2 != 0) goto 1; */
mov r0, r1
mov pc, lr
getenv: /* char* name -> char* */
stmfd sp!, {v1-v5, lr}
/* v1 = name */
mov v1, r0
/* v2 = strlen(r0) */
bl strlen
mov v2, r0
/* v3 = environ char** */
ldr v3, =environ
ldr v3, [v3]
1: /* if (strncmp(name, *environ, len) == 0) { */
mov r0, v1
ldr r1, [v3]
/* *environ != NULL */
cmp r1, $0x00
beq 2f
mov r2, v2
bl strncmp
cmp r0, $0x00
/* if (*environ)[len] == '=') { */
ldreq r0, [v3]
ldreqb r0, [r0, v2]
cmpeq r0, #'=
beq 3f
/* } */
/* environ++ */
add v3, $0x04
b 1b
2:
/* not found return NULL */
mov r0, $0x00
ldmfd sp!, {v1-v5, pc}
3: /* found and return address */
ldreq r0, [v3]
add r0, r0, v2
add r0, r0, $0x01 /* skip '=' */
ldmfd sp!, {v1-v5, pc}
puts:
stmfd sp!, {v1-v5, lr}
mov v1, r0
bl strlen
mov r2, r0
mov r1, v1
mov r0, $0x00
sys_write
mov r0, $0x00
adr r1, linefeed
mov r2, $0x01
sys_write
ldmfd sp!, {v1-v5, pc}
linefeed:
.byte '\n
.align 2
.section .bss
.align 2
environ: .word 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment