Created
March 14, 2014 10:09
-
-
Save cho45/9545176 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*#!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 (not used) */ | |
ldr r0, [sp] | |
/* r1 = argv (not used) */ | |
add r1, sp, $0x04 | |
/* r2 = argc * 4 (skip argv) */ | |
mov r3, $0x04 | |
mul r2, r0, r3 | |
/* skip null word */ | |
add r2, r2, $0x04 | |
add r2, r1 | |
/* save char** environ */ | |
ldr r0, environ_p | |
str r2, [r0] | |
adr r0, USER | |
bl getenv | |
mov v1, r0 | |
bl strlen | |
mov v2, r0 | |
mov r0, #0 | |
mov r1, v1 | |
mov r2, v2 | |
sys_write | |
/* hello, world */ | |
adr r0, msg | |
bl strlen | |
mov r2, r0 | |
mov r0, #0 | |
adr r1, msg | |
sys_write | |
mov r0, $0x00 /* set exit status to 0 */ | |
sys_exit | |
USER: | |
.asciz "USER" | |
.align 2 | |
msg: | |
.asciz "Hello, World\n" | |
.align 2 | |
environ_p: .word environ | |
strncmp: /* char* s1, char* s2, size_t len -> 1|0 */ | |
stmfd sp!, {v1-v5, lr} | |
mov r3, $0x00 /* result */ | |
1: cmp r2, $0x00 | |
beq 2f /* if (r2 == 0) goto 2 */ | |
sub r2, r2, $0x01 /* len-- */ | |
ldrb r4, [r0], $0x01 | |
ldrb r5, [r1], $0x01 | |
cmp r4, r5 | |
addne r3, $0x01 | |
beq 1b | |
2: | |
mov r0, r3 | |
ldmfd sp!, {v1-v5, pc} | |
strlen: /* char* str* -> uint */ | |
mov r1, $0x00 | |
/* 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_p | |
ldr v3, [v3] | |
1: /* if (strncmp(name, *environ, len) == 0) { */ | |
mov r0, v1 | |
ldr r1, [v3] | |
mov r2, v2 | |
bl strncmp | |
cmp r0, $0x00 | |
/* if (*environ)[len] == '=') { */ | |
ldreq r0, [v3] | |
ldreqb r0, [r0, v2] | |
cmpeq r0, $0x3d @ '=' | |
beq 2f | |
/* } */ | |
/* environ++ */ | |
add v3, $0x04 | |
/* *environ != NULL */ | |
ldr r1, [v3] | |
cmp r1, $0x00 | |
bne 1b | |
/* not found return NULL */ | |
mov r0, $0x00 | |
ldmfd sp!, {v1-v5, pc} | |
2: /* found and return address */ | |
ldreq r0, [v3] | |
add r0, r0, v2 | |
add r0, r0, $0x01 /* skip '=' */ | |
ldmfd sp!, {v1-v5, pc} | |
.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