liquinox 0 Newbie Poster

I am trying to convert a seemingly simple function written in C into assembly. My assembly subroutine seems to work, except when it returns to main, *pCombo contains garbage. When I step through the debugger, it seems to put the characters in the right place, I suspect there is an issue in one of my addressing modes but at this point I am not sure.

I have included the main program, as well as the function to print out the input read in the assembly subroutine.

GDB trace (abcd is the input):

make main.gdb
as --gstabs -o readCombo.o readCombo.s
gcc -g -c main.c
g++ -o main.out readCombo.o main.o
gdb main.out
(gdb) r
Starting program: /home2/mccoyd/main.out 
abcd
P�@

C Code

void readCombo(char *pCombo, unsigned n)
{
  char ch;
  int result;
  do
  {
    result = read(0, &ch, 1);
    if ((result != 0) and (n > 0))
    {
      *pCombo = ch;
      n = n - 1;
      pCombo = pCombo + 1;
    }
  }
  while (result && ch != 10);
}

int main(void)
{
  char x[5];
  char y[5];
  char nl = '\n';
  readCombo(x, sizeof(x));
  writeCombo(x, sizeof(x));
}

void writeCombo(const char *pCombo, unsigned n)
{
  while (n > 0)
  {
    write(1, pCombo, 1);
    pCombo = pCombo + 1;
    n = n - 1;
  }
}

Assembly code:

.text
.global readCombo

readCombo:
  oldEbp = 0
  retAddr = oldEbp + 4
  pCombo = retAddr+4
  n = pCombo + 4
  readChar = oldEbp - 4 # Place to store the input character

  # Save stack pointer
  pushl %ebp
  movl  %esp,%ebp

  # Allocate space for readChar, initialize to easy to see value
  pushl $999

  # Find the address of pCombo and put in %eax
  movl %ebp, %eax
  addl $pCombo, %eax

  # The start of the loop
  loopStart:

  # Get the address of readChar
  movl %ebp, %edx
  addl $readChar, %edx

  # Save the address of pCombo (in %eax)
  pushl %eax

  # Read a character and check
  movl  $3, %eax
  movl  $0, %ebx
  movl  %edx, %ecx
  movl  $1, %edx
  int   $0x80

  # Restore the address of pCombo from earlier
  popl %eax

  # Make sure the input character is above 0
  cmpb $0, (%ecx)
  jna checkConditional

    # Make sure n is above zero
    cmpb $0, n(%ebp)
    jna checkConditional

      # Move the character into a temp register
      movb (%ecx), %bl
      # Put the input character into where pCombo points to
      movb %bl, (%eax)

      # Find the address of n and put in %ebx
      movl %ebp, %ebx
      addl $n, %ebx
      # Subtract 1 from n
      subb $1, (%ebx)

      # Add one to the address of pCombo (saved in register %eax)
      addl $1, %eax

  checkConditional:

  # Make sure the input character is not 0 (null)
  cmpb $0, (%ecx)
  jna exitLoop

    # Make sure the input character is greater than 10 (line feed)
    cmpb $10, (%ecx)
    jna exitLoop

  # Go back to the start of the loop
  jmp loopStart

  # Break out of the loop
  exitLoop:

  # Pop the local variable readChar (housekeeping)
  popl %ecx

  movl  %ebp,%esp
  popl  %ebp
  ret