|
From: | Felix Chivite |
Subject: | [Pgubook-readers] toupper segmentation fault - please help - 2 |
Date: | Tue, 12 Jul 2005 02:13:51 +0100 (BST) |
After a few searches I've learned that this is probably a problem with memory addressing, or pointers or arrays. I've checked my source file against the original in the book many times but I can't see where I've gone wrong. Could anybody help? Thank you all in advance,
Felix (a complete beginner).
There follows a copy of my source file:
# Purpose: This program converts an input file to an output file with all the letters converted to # uppercase # Processing: 1. Open the input file # 2. Open the output file # 3. While we are not at the end of the input file # a. read part of file into our memory buffer # b. go through each bit of memory - if the byte is a lower case letter, convert to # uppercase # c. write the memory buffer to output file .section .data #CONSTANTS# #SYSTEM CALL NUMBERS - They go into eax .equ SYS_OPEN, 5 .equ SYS_WRITE, 4 .equ SYS_READ, 3 .equ SYS_CLOSE, 6 .equ SYS_EXIT, 1 #OPTIONS FOR OPEN FILE .equ O_RDONLY, 0 .equ O_CREAT_WRONLY_TRUNC, 03101 #STANDARD FILE DESCRIPTORS .equ STDIN, 0 .equ STDOUT, 1 .equ STERR, 2 #SYSTEM CALL INTERRUPT .equ LINUX_SYSCALL, 0x80 #RETURN VALUE OF READ - this means that we have reached the end of the file .equ END_OF_FILE, 0 .equ NUMBER_ARGUMENTS, 2 .section .bss #This is where the data is loded into from the data file and written from into the output file .equ BUFFER_SIZE, 500 .lcomm BUFFER_DATA, BUFFER_SIZE # this directive, .lcomm, will create a symbol, #BUFFER_DATA, that refers to a BUFFER_SIZE # storage location that we can use as a buffer .section .text #STACK POSITIONS .equ ST_SIZE_RESERVE, 8 .equ ST_FD_IN, -4 # FD means file descriptor .equ ST_FD_OUT, -8 # ARGV=file opening arguments automatically stored by Linux in the stack, #these take care # of the command line input automatically .equ ST_ARGC, 0 # number of arguments .equ ST_ARGV_0, 4 # name of program .equ ST_ARGV_1, 8 # name of input file .equ ST_ARGV_2, 12 # name of output file .globl _start _start: # INITIALISE PROGRAM movl %esp, %ebp # save the stack pointer subl $ST_SIZE_RESERVE, %esp # allocate space for our file descriptors, FD, on the stack open_files: # OPEN INPUT FILES open_fd_in: movl $SYS_OPEN, %eax # open system call movl ST_ARGV_1(%ebp), %ebx # input filename into ebx movl $O_RDONLY, %ecx # read only flag - read/write mode number movl $0666, %edx # permission number - not really necessary for reading int $LINUX_SYSCALL # call linux, the system call number is in eax store_fd_in: movl %eax, ST_FD_IN(%ebp) # store the file descriptor here (stack loc. -4) # OPEN OUTPUT FILES open_fd_out: movl $SYS_OPEN, %eax # open the output file movl ST_ARGV_2(%ebp), %ebx # filename goes into ebx movl $O_CREAT_WRONLY_TRUNC, %ecx # flag for writing to the file movl $0666, %edx # permission for creating file int $SYS_OPEN # call linux - system call number is in eax store_fd_out: movl %eax, ST_FD_OUT(%ebp) # store the file descriptor here (stack loc. -8) # BEGIN MAIN LOOP read_loop_begin: # read a block from the input file movl SYS_READ, %eax # system call code for reading (n.3) goes into eax movl ST_FD_IN(%ebp), %ebx # get the input file descriptor movl $BUFFER_DATA, %ecx # the location to read into movl $BUFFER_SIZE, %edx # indicate the size of the buffer int $LINUX_SYSCALL # size of buffer read is returned in eax # EXIT IF WE'VE REACHED THE END cmpl $END_OF_FILE, %eax # check if we have reached the end of file marker (n.0) jle end_loop # if found or in error, go to end continue_read_loop: # convert the block to upper case pushl $BUFFER_DATA # location of buffer pushl %eax # size of the buffer call convert_to_upper popl %eax # get the size back addl $4, %esp # restore %esp # WRITE BLOCK OUT TO OUTPUT FILE movl %eax, %edx movl $SYS_WRITE, %eax # system call n. movl ST_FD_OUT(%ebp), %ebx # file to use movl $BUFFER_DATA, %ecx # location of the buffer int $LINUX_SYSCALL # CONTINUE THE LOOP jmp read_loop_begin end_loop: # CLOSE THE FILES movl $SYS_CLOSE, %eax movl ST_FD_OUT(%ebp), %ebx # close output file int $LINUX_SYSCALL movl $SYS_CLOSE, %eax movl ST_FD_IN(%ebp), %ebx # close input file int $LINUX_SYSCALL # EXIT movl $SYS_EXIT, %eax movl $0, %ebx # exit status n. goes into ebx int $LINUX_SYSCALL # FUNCTION convert_to_upper # Purpose: this function does the conversion to upper case for a block # Input: the first parameter is the location of the block of memory to convert # the sencond is the length of that buffer # Variables: %eax - beginning of buffer # %ebx - legth of buffer # %edi - current buffer offset # %cl - current byte being examined (first part of %ecx) #CONSTANTS .equ LOWERCASE_A, 'a' # the lower boundary of our search - ASCII characters are inputed between apostrophes .equ LOWERCASE_Z, 'z' # the upper boundary of our search .equ UPPER_CONVERSION, 'A' - 'a' #STACK LOCATIONS, ETC .equ ST_BUFFER_LEN, 8 # Length of buffer .equ ST_BUFFER, 12 # actual buffer convert_to_upper: pushl %ebp movl %esp, %ebp # SET UP VARIABLES movl ST_BUFFER(%ebp), %eax movl ST_BUFFER_LEN(%ebp), %ebx movl $0, %edi cmpl $0, %ebx # if a buffer with zero length was given to us, exit je end_convert_loop # jump if equal convert_loop: movb (%eax,%edi,1), %cl # get the current byte cmpb $LOWERCASE_A, %cl jl next_byte # go to the next byte unless it is between 'a' and 'z' cmpb $LOWERCASE_Z, %cl jg next_byte # jump if second value greater than first # otherwise, convert to uppercase addb $UPPER_CONVERSION, %cl # and store it back movb %cl, (%eax, %edi,1) next_byte: incl %edi # load next byte cmpl %edi, %ebx jne convert_loop # continue unless we've reached the end end_convert_loop: movl %ebp, %esp popl %ebp ret
[Prev in Thread] | Current Thread | [Next in Thread] |