When writing and testing assembly code, I found myself hitting [up] [up] [up] a lot. After I did this routine about 50 times I decided it was time to automate my compiling for assembly.
I started my script out by just writing a file (cas.sh in my case - for Compile ASsembly) with the line:
$ vim cas.sh
nasm -f elf $1 #the $1 referrs to the first command line
#argument passed to the program
Now when I got to the second line, which was going to do the linking (i.e. $ld -s -o program program.asm) I realized I would need to do some string manipulation on the part of the name being passed to the script. Learning this part was neat, I'd never done this before, and thankfully it's really easy. What we want to do is to be able to strip off the .asm off the back of the name of the assembly file so we can attach a .o to reference the output file of nasm. To string match and remove off of the end of a string we put the variable name in braces {} and use a % followed by the string at the end to be removed, in our case it will look like ${1%.asm}. This will give us only the name of the file, with no .asm extension which we will use for the executable name. (Here are good references for strings in bash) To reference the compiled .o file, we will modify this only slightly to be ${1%asm}o. Note that we did not take off the '.' this time, so we will only need to add the 'o' at the end.
$ vim cas.sh
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
We have a working bash script to allow us to quickly compile our assembly source code to an executable. Next up is optimizations!
First up is to delete those .o files. They aren't very useful after the initial linking. That adds only a quick rm line in the script:
$ vim cas.sh
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
rm ${1%asm}o
Another way we can optimize is to enable backups of the .asm files before we compile them. We'll go ahead and put them into a subfolder in our current directory called bak. What if bak doesnt exist when we run the script? Well, I'm glad you asked. We can us an if-statement to check if the bak directory exists, and if it does no, we will then create a folder. If we do this before we create the backup then we will know the folder exists (unless something goes horribly wrong, then you'd have other issues to worry about...). In the if statement we can use the test directive to check if the directory already exists. Here is the proper syntax for this command:
$ vim cas.sh
if [ ! -d bak ]; then # the ! means not, so this says if the directory
# does not exist, then do what follows
mkdir bak
fi
cp $1 bak/$1.bak #dont forget to create the actual backup
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
rm ${1%asm}o
As your script gets more and more complicated, it can be helpful to comment out tricky sections of code for future reference. It can be nice if you need to do something in a new script and cant remember exactly how or why you did something in a previous script, or to give yourself a quick syntax summary so you can figure it out a bit easier next time.
Another thing I added to my script was to put the entire script into an if-statement that checked if the file that you were planning on compiling even exists. I doubt this is really needed, but I felt like putting it in there so skip down a bit if this is boring you.
$ vim cas.sh
if [ -e $1 ]; then #this checks to make sure the file exists
if [ ! -d bak ]; then
mkdir bak
fi
cp $1 bak/$1.bak
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
rm ${1%asm}o
fi
The last thing I did when I felt like the file was complete was to move/copy/link it to /usr/sbin/cas. Now you can use it just by typing cas at the command line instead of $sh cas.sh or even $./cas.sh if you made the file executable.
Hopefully this was helpful to somebody. Just though I'd share what I learned recently.
geno
I started my script out by just writing a file (cas.sh in my case - for Compile ASsembly) with the line:
$ vim cas.sh
nasm -f elf $1 #the $1 referrs to the first command line
#argument passed to the program
Now when I got to the second line, which was going to do the linking (i.e. $ld -s -o program program.asm) I realized I would need to do some string manipulation on the part of the name being passed to the script. Learning this part was neat, I'd never done this before, and thankfully it's really easy. What we want to do is to be able to strip off the .asm off the back of the name of the assembly file so we can attach a .o to reference the output file of nasm. To string match and remove off of the end of a string we put the variable name in braces {} and use a % followed by the string at the end to be removed, in our case it will look like ${1%.asm}. This will give us only the name of the file, with no .asm extension which we will use for the executable name. (Here are good references for strings in bash) To reference the compiled .o file, we will modify this only slightly to be ${1%asm}o. Note that we did not take off the '.' this time, so we will only need to add the 'o' at the end.
$ vim cas.sh
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
We have a working bash script to allow us to quickly compile our assembly source code to an executable. Next up is optimizations!
First up is to delete those .o files. They aren't very useful after the initial linking. That adds only a quick rm line in the script:
$ vim cas.sh
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
rm ${1%asm}o
Another way we can optimize is to enable backups of the .asm files before we compile them. We'll go ahead and put them into a subfolder in our current directory called bak. What if bak doesnt exist when we run the script? Well, I'm glad you asked. We can us an if-statement to check if the bak directory exists, and if it does no, we will then create a folder. If we do this before we create the backup then we will know the folder exists (unless something goes horribly wrong, then you'd have other issues to worry about...). In the if statement we can use the test directive to check if the directory already exists. Here is the proper syntax for this command:
$ vim cas.sh
if [ ! -d bak ]; then # the ! means not, so this says if the directory
# does not exist, then do what follows
mkdir bak
fi
cp $1 bak/$1.bak #dont forget to create the actual backup
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
rm ${1%asm}o
As your script gets more and more complicated, it can be helpful to comment out tricky sections of code for future reference. It can be nice if you need to do something in a new script and cant remember exactly how or why you did something in a previous script, or to give yourself a quick syntax summary so you can figure it out a bit easier next time.
Another thing I added to my script was to put the entire script into an if-statement that checked if the file that you were planning on compiling even exists. I doubt this is really needed, but I felt like putting it in there so skip down a bit if this is boring you.
$ vim cas.sh
if [ -e $1 ]; then #this checks to make sure the file exists
if [ ! -d bak ]; then
mkdir bak
fi
cp $1 bak/$1.bak
nasm -f elf $1
ld -s -o ${1%.asm} ${1%asm}o
rm ${1%asm}o
fi
The last thing I did when I felt like the file was complete was to move/copy/link it to /usr/sbin/cas. Now you can use it just by typing cas at the command line instead of $sh cas.sh or even $./cas.sh if you made the file executable.
Hopefully this was helpful to somebody. Just though I'd share what I learned recently.
geno
Comments
Post a Comment