in the name of zero

January 29, 2006

assemblifying a bash script

first and foremost, to my chinese brothers and sisters out there,

“xin nian kuai le”

way back, i frequently found myself descending deep into the recesses of my git repository. i keep all sorts of stuff there. but more importantly, i keep all my work neatly categorized in special folders inside. anyway, i decided to come up with some remedy, enter bash scripting. i made a (pretty much) straight forward script to create a symlink in my home directory called “workdir” so if ever i wanted to go back to my work, i’d only cd ~/workdir right away.

#!/bin/bash
	
# this script makes a symlink "~/workdir" to
# the pwd or to the first argument
	
CWD=`pwd`
SHORTCUT=/home/amerei/workdir
	
# create a symlink
# if a symlink exists remove it first
function my_linkie {
	if [ -h $SHORTCUT ]; then
		rm $SHORTCUT
	fi
	
	ln -s $CWD $SHORTCUT
	
	exit 0
}
	
# if there are no arguments assume
# current directory to be the target
# otherwise, honor only the first argument
if [ $# = 0 ] ; then
	my_linkie
else
	# i don't want a broken symlink
	# file exists and is a directory
	if [ -d $1 ]; then
		CWD=$1
		my_linkie
	fi
	echo "$1 is invalid"
	exit 1
fi
one day, i was bored so i tried to implement the script above in assembly. here goes..

; /usr/include/asm/unistd.h
%define sys_stat	0x6a
%define	sys_symlink	0x53
%define	sys_readlink	0x55
%define sys_unlink	0x0a
	
; /usr/include/asm/errno.h
%define	EEXIST		-0x11
	
; st_mode field (man 2 stat)
%define S_IFDIR		0040000q
	
; custom definitions
%define bufsiz		0x20000	; enough length?
	
; /usr/include/asm/stat.h
struc _stat
	.st_dev		resw	1
	.__pad1		resw	1
	.st_ino		resd	1
	.st_mode	resw	1
	.st_nlink	resw	1
	.st_uid		resw	1
	.st_gid		resw	1
	.st_rdev	resw	1
	.__pad2		resd	1
	.st_size	resd	1
	.st_blksize	resd	1
	.st_blocks	resd	1
	.st_atime	resd	1
	.__unused1	resd	1
	.st_mtime	resd	1
	.__unused2	resd	1
	.st_ctime	resd	1
	.__unused3	resd	1
	.__unused4	resd	1
	.__unused5	resd	1
endstruc
	
	shortcut: db '/home/amerei/workdir',0x0
	proc_cwd: db '/proc/self/cwd', 0x0
	
	global _start
section .text
_start:
	pop ebx		; argc
	dec ebx
	pop ebx		; argv[0]
	jnz .getargv	; has arguments
	
.getcwd
	
	mov edx, bufsiz		; bufsiz
	mov ecx, pwd		; char *buf
	mov ebx, proc_cwd	; const char *path
	mov eax, sys_readlink	; sys_readlink()
	int 80h
	test eax, eax		; toggle sign flag
	js error		; exit(errno)
	
	mov edi, pwd		; see .mylinkie
	jmp .mylinkie
	
.getargv:
	pop edi			; first argument
	
	mov ecx, stat_buf	; struct stat *buf
	mov ebx, edi		; const char *filename
	mov eax, sys_stat	; sys_stat()
	int 0x80
	
	test eax, eax		; toggle sign flag
	js error		; exit(errno)
	
	mov eax, [stat_buf+_stat.st_mode]
	mov ebx, S_IFDIR
	test eax, ebx
	jz error		; file is not a folder
	
.mylinkie:
	mov ecx, shortcut	; const char *newpath
	mov ebx, edi		; const char *oldpath
	mov eax, sys_symlink	; sys_symlink()
	int 0x80
	
	test eax, eax		; toggle sign flag
	jns .bye
	
	cmp eax, EEXIST		; check for EEXIST
	jne error
	
	mov ebx, shortcut
	mov eax, sys_unlink
	int 80h
	
	test eax, eax		; bugger!
	js error		; deal with it.
	jmp .mylinkie		; another shot
	
.bye:
	xor eax, eax
	inc eax
	xor ebx, ebx
	int 80h
	
error:
	mov ebx, eax
	neg ebx			; -(eax) = errno
	mov eax, 1
	int 80h
	
section .bss
	stat_buf	resb _stat_size
	pwd		resb bufsiz
i had a hard time on how to implement strucs in nasm. again, thanks to frank kotler i kinda got the hang of those. he confirmed that i needed to create an instance of a struc as opposed to just prototyping one inside the .bss segment the only thing i hate about that implementation above is that i have to declare an entire stat structure but use only one of it’s elements. it’s current standing size is 596 bytes! and if i compare that to the bash script version’s size of 598 bytes, i think i did a rather pathetic job. there are just some things that are better off scripted. oh well, at least i learned how to use sys_stat to get some basic file information. currently, i’m psyching myself out to tackle streaming SIMD extensions in pentium III (sse). i hope i won’t lose my mind trying to understand that!

oh! and yeah… to steph,

praying for better times.
wishing you a belated happy birthday.

from your biggest fan,
-me

Comments »

The URI to TrackBack this entry is: http://gnurbs.blogsome.com/2006/01/29/assemblifying-a-bash-script/trackback/

No comments yet.

RSS feed for comments on this post.

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>


Get free blog up and running in minutes with Blogsome | Theme designs available here