Results 1 to 10 of 10

Thread: [SOLVED] Programming from the Ground Up (Assembly)

  1. #1
    Join Date
    Apr 2007
    Location
    Internet
    Beans
    174
    Distro
    Ubuntu 8.04 Hardy Heron

    [SOLVED] Programming from the Ground Up (Assembly)

    I hate it when you copy and paste from a book and the program doesn't work like it should. I have the book Programming from the Ground Up and I copy and paste the programs and see them work, then I read the description. However, I had 3 errors.

    Here's the program they gave:
    Code:
    #PURPOSE:     This program converts an input file to an output file with all
    #             letters converted to uppercase.
    #
    #PROCESSING:  1) Open the input file
    #             2) Open the output file
    #             4) While we’re not at the end of the input file
    #                a) read part of the file into our piece of memory
    #                b) go through each byte of memory
    #                     if the byte is a lower-case letter, convert it to uppercase
    #                c) write the piece of memory to the output file
      .section .data
    #######CONSTANTS########
      #system call numbers
      .equ SYS_OPEN, 5
      .equ SYS_WRITE, 4
      .equ SYS_READ, 3
      .equ SYS_CLOSE, 6
      .equ SYS_EXIT, 1
      #options for open() (look at /usr/include/asm/fcntl.h for
      #                    various values. You can combine them
      #                    by adding them)
      .equ O_RDONLY, 0
      .equ O_CREAT_WRONLY_TRUNC, 03101
      #standard file descriptors
      .equ STDIN, 0
      .equ STDOUT, 1
      .equ STDERR, 2
    
     #system call interrupt
     .equ LINUX_SYSCALL, 0x80
     .equ END_OF_FILE, 0         #This is the return value of read() which
                                 #means we’ve hit the end of the file
     .equ NUMBER_ARGUMENTS, 2
    .section .bss
     #Buffer - this is where the data is loaded into from
     #           the data file and written from into the output file.       This
     #           should never exceed 16,000 for various reasons.
     .equ BUFFER_SIZE, 500
     .lcomm BUFFER_DATA, BUFFER_SIZE
     .section .text
     #STACK POSITIONS
     .equ ST_SIZE_RESERVE, 8
     .equ ST_FD_IN, -4
     .equ ST_FD_OUT, -8
     .equ ST_ARGC, 0             #Number of arguments
     .equ ST_ARGV_0, 4          #Name of program
     .equ ST_ARGV_1, 8          #Input file name
     .equ ST_ARGV_2, 12          #Output file name
     .globl _start
    _start:
     ###INITIALIZE PROGRAM###
     #save the stack pointer
     movl %esp, %ebp
     #Allocate space for our file descriptors on the stack
     subl $ST_SIZE_RESERVE, %esp
    open_files:
    open_fd_in:
     ###OPEN INPUT FILE###
     movl $SYS_OPEN, %eax                    #open syscall
     movl ST_ARGV_1(%ebp), %ebx          #input filename into %ebx
     movl $O_RDONLY, %ecx                #read-only flag
     movl $0666, %edx                    #this doesn’t really matter for reading
     int     $LINUX_SYSCALL              #call Linux
    store_fd_in:
    
     movl  %eax, ST_FD_IN(%ebp)   #save the given file descriptor
    open_fd_out:
     ###OPEN OUTPUT FILE###
     movl $SYS_OPEN, %eax                    #open the file
     movl ST_ARGV_2(%ebp), %ebx          #output filename into %ebx
     movl $O_CREAT_WRONLY_TRUNC, %ecx    #flags for writing to the file
     movl $0666, %edx                    #mode for new file (if it’s created)
     int   $LINUX_SYSCALL                #call Linux
    store_fd_out:
     movl %eax, ST_FD_OUT(%ebp)        #store the file descriptor here
     ###BEGIN MAIN LOOP###
    read_loop_begin:
     ###READ IN A BLOCK FROM THE INPUT FILE###
     movl $SYS_READ, %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        #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 for end of file marker
     jle   end_loop                 #if found or on error, go to the end
    continue_read_loop:
     ###CONVERT THE BLOCK TO UPPER CASE###
     pushl $BUFFER_DATA             #location of the buffer
     pushl %eax                     #size of the buffer
     call convert_to_upper
     popl %eax                      #get the size of the read back
     addl $4, %esp                  #move the stack the rest of the
                                    #way back
     ###WRITE THE BLOCK OUT TO THE OUTPUT FILE###
     movl %eax, %edx                #size of the buffer
     movl $SYS_WRITE, %eax
     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###
      #NOTE - we don’t need to do error checking on these, because
      #        error conditions don’t signify anything special here
      movl $SYS_CLOSE, %eax
      movl ST_FD_OUT(%ebp), %ebx
      int    $LINUX_SYSCALL
      movl   $SYS_CLOSE, %eax
      movl   ST_FD_IN(%ebp), %ebx
      int    $LINUX_SYSCALL
      ###EXIT###
      movl $SYS_EXIT, %eax
      movl $0, %ebx
      int    $LINUX_SYSCALL
    #PURPOSE:      This function actually does the conversion to upper case for a block
    #
    #INPUT:        The first parameter is the location of the block of memory to convert
    #              The second parameter is the length of that buffer
    #
    #OUTPUT:       This function overwrites the current buffer with the upper-casified
    #              version.
    #
    #VARIABLES:
    #              %eax - beginning of buffer
    #              %ebx - length 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
      .equ LOWERCASE_Z, z                 #The upper boundary of our search
      .equ UPPER_CONVERSION, ’A’ - ’a’      #Conversion between upper and lower case
      ###STACK STUFF###
      .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
     #if a buffer with zero length was given us, just leave
     cmpl $0, %ebx
     je    end_convert_loop
    convert_loop:
     #get the current byte
     movb (%eax,%edi,1), %cl
     #go to the next byte unless it is between ’a’ and ’z’
     cmpb $LOWERCASE_A, %cl
     jl    next_byte
     cmpb $LOWERCASE_Z, %cl
     jg    next_byte
     #otherwise convert the byte to uppercase
     addb $UPPER_CONVERSION, %cl
     #and store it back
     movb %cl, (%eax,%edi,1)
    next_byte:
     incl %edi               #next byte
     cmpl %edi, %ebx         #continue unless we’ve reached the end
     jne   convert_loop
    end_convert_loop:
     #no return value, just leave
     movl %ebp, %esp
     popl %ebp
     ret
    If you copy and paste this into an editor to see the line numbers, I had an error at 134, 135, and 136.
    At 134, it says
    Code:
    Error: undefined symbol `’A’' in operation setting `UPPER_CONVERSION'
    Error: undefined symbol `’a’' in operation setting `UPPER_CONVERSION'
    I changed that line to
    Code:
    .equ UPPER_CONVERSION, ’-32
    and it assembles.

    I link it and get this:
    Code:
    toupper.o: In function `convert_loop':
    (.text+0xa6): undefined reference to `’a’'
    toupper.o: In function `convert_loop':
    (.text+0xab): undefined reference to `’z’'
    Can I have some help here? Thanks!
    I'M USING CAPSLOCK.

  2. #2
    Join Date
    Aug 2008
    Beans
    Hidden!

    Re: Programming from the Ground Up (Assembly)

    I'd think that all those errors you mention lie in that part of the code:
    Code:
      ###CONSTANTS##
      .equ LOWERCASE_A, a                 #The lower boundary of our search
      .equ LOWERCASE_Z, z                 #The upper boundary of our search
      .equ UPPER_CONVERSION, ’A’ - ’a’      #Conversion between upper and lower case
    In order to learn something about Assembly, I'd suggest to study closely what the .equ statement does and how letters can be used as "numerical" values in this context, i.e. in Assembly arithmetics.

    Also, you might want to check if your text editor somehow changes single quotes into other characters.

  3. #3
    Join Date
    Apr 2007
    Location
    Internet
    Beans
    174
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: Programming from the Ground Up (Assembly)

    They do lie in that part of the code. I realize that .equ makes a string of letters a constant with a numeric value. I also realize that letters have ASCII values which are numbers. My problem is that it's straight copy and paste and it doesn't work. I'm using gedit and assembling with as and linking with ld as intructed. Maybe it's a problem with gedit but that's how it is in the book.

    Here's the book I'm reading. It's available free online.
    http://nongnu.askapache.com/pgubook/...0-booksize.pdf

    It's from pages 57 to 61 but in a pdf reader, that's 63 to 67.
    Last edited by Stoodle; December 31st, 2008 at 07:19 PM. Reason: Here's the book.
    I'M USING CAPSLOCK.

  4. #4
    Join Date
    Aug 2008
    Beans
    Hidden!

    Re: Programming from the Ground Up (Assembly)

    Sorry, I thought you wanted help with learning the Assembly language when you wanted to complain about the examples in the book not being executable.

    Anyway, being a bit bored right now I went and had a look at the PDF you linked to in your post above.

    I presume that the code example is the one on page 92 in the PDF doc (the one with the page number '86' printed on the bottom of the page).

    I find the following bit of code there:

    Code:
    ###CONSTANTS##
    #The lower boundary of our search
    .equ LOWERCASE_A, ’a’
    #The upper boundary of our search
    .equ LOWERCASE_Z, ’z’
    #Conversion between upper and lower case
    .equ UPPER_CONVERSION, ’A’ - ’a’
    which is not quite the same as in your first post.

    Again, you might want to read up on how to use letters when you want to refer to their ordinal values as opposed to using them as "symbols" or "identifiers".

  5. #5
    Join Date
    Jun 2006
    Location
    CT, USA
    Beans
    5,267
    Distro
    Ubuntu 6.10 Edgy

    Re: Programming from the Ground Up (Assembly)

    Quote Originally Posted by pp. View Post
    Sorry, I thought you wanted help with learning the Assembly language when you wanted to complain about the examples in the book not being executable.
    That's common problem with computer books that typesetting will mess up syntax. Get used to it. Good authors provide website where you can download the code as plain text files, and run validation tests to make sure code works.

  6. #6
    Join Date
    Apr 2007
    Location
    Internet
    Beans
    174
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: Programming from the Ground Up (Assembly)

    Ah! The problem was that you must refer to single characters with one single quote such as 'a or 'b.
    I'M USING CAPSLOCK.

  7. #7
    Join Date
    Jan 2006
    Beans
    Hidden!
    Distro
    Ubuntu 10.10 Maverick Meerkat

    Re: Programming from the Ground Up (Assembly)

    it's actually 'a' or 'b' (enclosed by single quotes), this also works the same way in C.
    I am infallible, you should know that by now.
    "My favorite language is call STAR. It's extremely concise. It has exactly one verb '*', which does exactly what I want at the moment." --Larry Wall
    (02:15:31 PM) ***TimToady and snake oil go way back...
    42 lines of Perl - SHI - Home Site

  8. #8
    Join Date
    Apr 2007
    Location
    Internet
    Beans
    174
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: [SOLVED] Programming from the Ground Up (Assembly)

    No, not in GAS assembly. You can only use one single quote. I was assembling with as and linking with ld. Copy and paste it.
    I'M USING CAPSLOCK.

  9. #9
    Join Date
    Jul 2005
    Location
    Northern CA
    Beans
    657
    Distro
    Ubuntu 20.04 Focal Fossa

    Re: [SOLVED] Programming from the Ground Up (Assembly)

    I hope that I'm not offending Stoodle here, but he has made a mistake that I (and I'm sure many others) have made many times in the past. His/her solution to the problem works and is correct, but for the wrong reason.

    We all copy/paste source code as a learning tool. To help avoid the frustrations similar to Stroodle's, I have posted a "HOWNOTTO" at http://ubuntuforums.org/showthread.p...56#post6508156
    Intel i7-920; Nvidia GT 220, 1GB; MSI X58 Pro-E; 6GB DDR; 64-bit mode.

  10. #10
    Join Date
    Feb 2009
    Location
    the semi-desert
    Beans
    4

    Re: [SOLVED] Programming from the Ground Up (Assembly)

    Rplantz wins with most courteous and informative post.

    If you're just glancing over the thread and have the same problem as stoodle (as I did) the problem is ’ vs ' you want a vertical apostrophe not an angled one.
    Last edited by Mr.Fluke; February 20th, 2009 at 04:33 AM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •