Team LiB
Previous Section Next Section

Making Our Program More Robust

This section will go through making the add-year.s program from Chapter 6 a little more robust.

Since this is a pretty simple program, we will limit ourselves to a single recovery point that covers the whole program. The only thing we will do to recover is to print the error and exit. The code to do that is pretty simple:

 .include "linux.s"
 .equ ST_ERROR_CODE, 8
 .equ ST_ERROR_MSG, 12
 .globl error_exit
 .type error_exit, @function
error_exit:
 pushl %ebp
 movl  %esp, %ebp
#Write out error code
movl  ST_ERROR_CODE(%ebp), %ecx
pushl %ecx
call  count_chars
popl  %ecx
movl  %eax, %edx
movl  $STDERR, %ebx
movl  $SYS_WRITE, %eax
int   $LINUX_SYSCALL

#Write out error message
movl  ST_ERROR_MSG(%ebp), %ecx
pushl %ecx
call  count_chars
popl  %ecx
movl  %eax, %edx
movl  $STDERR, %ebx
movl  $SYS_WRITE, %eax
int   $LINUX_SYSCALL

pushl $STDERR
call  write_newline

#Exit with status 1
movl  $SYS_EXIT, %eax
movl  $1, %ebx
int   $LINUX_SYSCALL

Enter it in a file called error-exit.s. To call it, you just need to push the address of an error message, and then an error code onto the stack, and call the function.

Now let's look for potential error spots in our add-year program. First of all, we don't check to see if either of our open system calls actually complete properly.

Linux returns its status code in %eax, so we need to check and see if there is an error.

 #Open file for reading
 movl  $SYS_OPEN, %eax
 movl  $input_file_name, %ebx
 movl  $0, %ecx
 movl  $0666, %edx
 int   $LINUX_SYSCALL

 movl  %eax, INPUT_DESCRIPTOR(%ebp)

 #This will test and see if %eax is
 #negative.  If it is not negative, it
 #will jump to continue_processing.
 #Otherwise it will handle the error
 #condition that the negative number
 #represents.
 cmpl  $0, %eax
 jl    continue_processing


 #Send the error
 .section .data
no_open_file_code:
 .ascii "0001: \0"
no_open_file_msg:
 .ascii "Can't Open Input File\0"

 .section .text
 pushl  $no_open_file_msg
 pushl  $no_open_file_code
 call   error_exit

continue_processing:
 #Rest of program

So, after calling the system call, we check and see if we have an error by checking to see if the result of the system call is less than zero. If so, we call our error reporting and exit routine.

After every system call, function call, or instruction which can have erroneous results you should add error checking and handling code.

To assemble and link the files, do:

as add-year.s -o add-year.o
as error-exit.s -o error-exit.o
ld add-year.o write-newline.o error-exit.o read-record.o write-
record.o count-chars.o -o add-year

Now try to run it without the necessary files. It now exits cleanly and gracefully!


Team LiB
Previous Section Next Section