151 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
	.globl _argv
 | 
						|
	.data
 | 
						|
	.align 4
 | 
						|
	.comm	argstr,256,4
 | 
						|
_argv:	.long	0
 | 
						|
 | 
						|
	.text
 | 
						|
	.globl start
 | 
						|
start:
 | 
						|
	# clear bss (could be done better)
 | 
						|
	# is it actually necessary?
 | 
						|
	mov	$__bss,%eax
 | 
						|
1:
 | 
						|
	movb	$0,(%eax)
 | 
						|
	inc	%eax
 | 
						|
	cmp	$__ebss,%eax
 | 
						|
	jbe	1b
 | 
						|
 | 
						|
	# copy command line args (can't use them directly, not aligned)
 | 
						|
	mov	%esp,%eax
 | 
						|
	shr	$2,%eax
 | 
						|
	mov	%eax,_argv
 | 
						|
	mov	(%esp),%ecx	# number of arguments
 | 
						|
	mov	$argstr,%edi
 | 
						|
1:
 | 
						|
	mov	(%esp,%ecx,4),%esi
 | 
						|
	mov	%edi,%eax
 | 
						|
	shr	$2,%eax
 | 
						|
	mov	%eax,(%esp,%ecx,4)
 | 
						|
	call	cpystr
 | 
						|
	loop	1b
 | 
						|
 | 
						|
	call	bsymbs
 | 
						|
	mov	_main,%eax
 | 
						|
	shl	$2,%eax
 | 
						|
	call	*%eax
 | 
						|
	mov	%eax,%ebx
 | 
						|
	mov	$1,%eax
 | 
						|
	int	$0x80
 | 
						|
 | 
						|
# copy string from esi to edi and convert '\0' to B's '*e', align edi
 | 
						|
cpystr:
 | 
						|
	mov	(%esi),%al
 | 
						|
	test	%al,%al
 | 
						|
	jz	1f
 | 
						|
	mov	%al,(%edi)
 | 
						|
	inc	%edi
 | 
						|
	inc	%esi
 | 
						|
	jmp	cpystr
 | 
						|
1:
 | 
						|
	movb	$04,(%edi)
 | 
						|
	inc	%edi
 | 
						|
	add	$3,%edi
 | 
						|
	and	$~3,%edi
 | 
						|
	ret
 | 
						|
 | 
						|
# shift addresses filled in by the linker 2 bits to the right
 | 
						|
# so B only ever sees word addresses
 | 
						|
bsymbs:
 | 
						|
	mov	$__bsymb,%eax
 | 
						|
1:
 | 
						|
	cmp	$__ebsymb,%eax
 | 
						|
	jge	1f
 | 
						|
	mov	(%eax),%ebx
 | 
						|
	mov	(%ebx),%ecx
 | 
						|
	shr	$2,%ecx
 | 
						|
	mov	%ecx,(%ebx)
 | 
						|
	add	$4,%eax
 | 
						|
	jmp	1b
 | 
						|
1:
 | 
						|
	ret
 | 
						|
 | 
						|
	.globl retrn
 | 
						|
retrn:
 | 
						|
	mov	%ebp,%esp
 | 
						|
	pop	%ebp
 | 
						|
	ret
 | 
						|
 | 
						|
# handle switch table:
 | 
						|
# eax has the value, ebx the address of the switch table
 | 
						|
	.globl bswitch
 | 
						|
bswitch:
 | 
						|
	xor	%ecx,%ecx
 | 
						|
1:
 | 
						|
	mov	(%ebx,%ecx,8),%edx
 | 
						|
	mov	4(%ebx,%ecx,8),%edi
 | 
						|
	test	%edi,%edi
 | 
						|
	jz	1f		# default (last in table)
 | 
						|
	cmp	%eax,%edx
 | 
						|
	je	2f
 | 
						|
	inc	%ecx
 | 
						|
	jmp	1b
 | 
						|
1:
 | 
						|
	jmp	*%edx
 | 
						|
2:
 | 
						|
	jmp	*%edi
 | 
						|
 | 
						|
#
 | 
						|
# Library functions in assembly
 | 
						|
#
 | 
						|
	.globl _exit
 | 
						|
	.data
 | 
						|
	.align 4
 | 
						|
	.section .bsymb; .long _exit; .data
 | 
						|
_exit:	.long	1f
 | 
						|
	.text
 | 
						|
	.align 4
 | 
						|
1:	mov	$1,%eax
 | 
						|
	mov	$0,%ebx
 | 
						|
	int	$0x80
 | 
						|
 | 
						|
	.globl _write
 | 
						|
	.data
 | 
						|
	.align 4
 | 
						|
	.section .bsymb; .long _write; .data
 | 
						|
_write:	.long	1f
 | 
						|
	.text
 | 
						|
	.align 4
 | 
						|
1:	mov	4(%esp),%ebx
 | 
						|
	mov	8(%esp),%ecx
 | 
						|
	shl	$2,%ecx
 | 
						|
	mov	12(%esp),%edx
 | 
						|
	mov	$4,%eax
 | 
						|
	int	$0x80
 | 
						|
	ret
 | 
						|
 | 
						|
	.globl _read
 | 
						|
	.data
 | 
						|
	.align 4
 | 
						|
	.section .bsymb; .long _read; .data
 | 
						|
_read:	.long	1f
 | 
						|
	.text
 | 
						|
	.align 4
 | 
						|
1:	mov	4(%esp),%ebx
 | 
						|
	mov	8(%esp),%ecx
 | 
						|
	shl	$2,%ecx
 | 
						|
	mov	12(%esp),%edx
 | 
						|
	mov	$3,%eax
 | 
						|
	int	$0x80
 | 
						|
	ret
 | 
						|
 | 
						|
	.globl	_inv
 | 
						|
	.data
 | 
						|
	.align 4
 | 
						|
	.section .bsymb; .long _inv; .data
 | 
						|
_inv:	.long	1f
 | 
						|
	.text
 | 
						|
	.align 4
 | 
						|
1:	mov	4(%esp),%eax
 | 
						|
	not	%eax
 | 
						|
	ret
 |