I have a piece of code here that I have some problem with. Most parts (subroutines)of the code works fine. There are 12 subroutines that I'm supposed to make work. You can say that they are like copies from the standard library. I'm only supposed to use fgets and puts from the standard library. The routines are inimage- uses fgets in order to get the numbers in %eax , getint - converts character to integer, gettext - reads what we get from fgets in %eax and puts the read numbers in a new buffer - INBUFFERT. setinpos - sets the position in the INBUFFERT, getinpos- returns the position and getchar - reads the character. Outimage - prints what is in UTBUFFERT, puttext- takes a string, puts it in a buffer, UTBUFFERT, putint - converts the integer to character and to a string and puts it in UTBUFFERT.
putchar - puts in a character (+ or =), getoutpos - returns the position, setoutpos - sets position to n. Another thing is that I have to keep track of the position.
.data Head: .asciz "Start of testprogram.Put in 2 numbers!" Show_Integ: .asciz "%d\n" Buf: .skip 316 N: .long 0 T: .long 0 Show: .asciz "%s\n" Sum: .long 0 Intg: .long 0 MAXPOS: .long 0 START_INPOS: .long 0 END_INPOS: .long 0 START_OUTPOS: .long 0 END_OUTPOS: .long 0 UTBUFFERT: .skip 128 INBUFFERT: .skip 128 .text .globl main, puttext, outimage, inimage, getint main: /*main,Upp and pp1 is part of the testprogram*/ pushl $Head /*Head is pushed on to the stack*/ call puttext /*This piece of text is now being pointed to the buffer UTBUFFERT*/ call outimage /*The text is taken from UTBUFFERT and is written on the screen*/ call inimage movl $2, N Upp: call getint movl %eax ,T pp1: movl T, %edx addl %edx, Sum pushl %edx call putint pushl $'+' call putchar decl N cmpl $0, N jne Upp call getoutpos decl %eax pushl %eax call setoutpos pushl '=' call putchar pushl Sum call putint call outimage call exit puttext: pushl %ebp movl %esp, %ebp movl $UTBUFFERT, %ecx movl 8(%ebp), %ebx next: movb (%ebx), %al cmpb $0, %al je puttextLoopEnd movb %al, (%ecx) incb %cl incb %bl jmp next puttextLoopEnd: movl %ebp, %esp popl %ebp ret outimage: pushl $UTBUFFERT /*pushl $Show*/ call puts addl $4, %esp ret inimage: /*Inimage uses fgets so that we with gettext can read in the numbers from the keyboard*/ pushl stdin pushl $79 pushl $Buf call fgets /*the numbers being typed in is now in %eax*/ addl $12,%esp xorl %ecx, %ecx /*position = 0*/ gettext: movl $INBUFFERT, %ebx gettext_loop: movb (%eax), %dl cmpb $10, %dl /*When I've put in two numbers and hit carriage return, = $13*/ /*this will be the endpoint and when done we jump to end_gettext*/ je end_gettext movb %dl, (%ebx) incl %eax incl %ebx incl %ecx jmp gettext_loop end_gettext: incl %ebx movb $32, (%ebx) movl %ecx, MAXPOS xorl %ecx, %ecx ret getint: movl $1, %edi movl $0, T movl END_INPOS, %ecx movl $0, END_INPOS setinpos: movl %ecx, START_INPOS cmpl $0, %ecx jb setinpos_zero cmpl MAXPOS, %ecx jg setinpos_max jmp getinpos setinpos_zero: movl $0, %ecx movl %ecx,START_INPOS jmp getinpos setinpos_max: movl MAXPOS, %ecx movl %ecx, START_INPOS jmp getinpos getinpos: movl START_INPOS, %ecx movl %ecx, %ebx getchar: movl $INBUFFERT, %ebx xorl %eax, %eax /*cmpb $45, (%ebx) je increase_charN */ getchar_loop: cmpb $32, (%ebx) je increase_char movsx (%ebx), %eax pushl %eax incl %ecx incl %ebx jmp getchar_loop increase_char: incl %ecx movl %ecx, END_INPOS decl %ecx getint_loop: cmpl START_INPOS, %ecx je getint_end popl %eax subl $48, %eax imul %edi, %eax addl %eax, Intg imul $10, %edi decl %ecx jmp getint_loop getint_end: xorl %eax, %eax movl Intg, %eax movl $0, Intg ret putint: pushl %ebp movl %esp, %ebp xorl %eax, %eax movl $10, %edi /*subl $4, %esp*/ movl 8(%ebp), %eax xorl %ecx, %ecx movl END_OUTPOS, %ecx movl %ecx, START_OUTPOS movl $0, END_OUTPOS putint_loop: movl $0, %edx idivl %edi addl $48, %edx pushl %edx incl %ecx cmpl $0, %eax je end_putint_loop jmp putint_loop end_putint_loop: xorl %eax, %eax xorl %ebx, %ebx xorl %edx, %edx movl $UTBUFFERT, %ebx movl %ecx,END_OUTPOS copy_reversing_loop: cmpl START_OUTPOS, %ecx je end_copy_reversing_loop decl %ecx popl %edx /*movzx (%edx), %ebx*/ movb %dl, %al movb %al, (%ebx) incl %ebx jmp copy_reversing_loop end_copy_reversing_loop: xorl %ebx, %ebx movl %ebp, %esp /*addl $4, %esp*/ popl %ebp ret putchar: pushl %ebp movl %esp, %ebp xorl %eax, %eax xorl %edx, %edx movl 8(%ebp), %eax movl $UTBUFFERT, %edx movl END_OUTPOS, %ecx movb %al, (%edx) incl %ecx movl %ecx, END_OUTPOS movl %ebp, %esp /*addl $4, %esp*/ popl %ebp ret getoutpos: xorl %eax, %eax movl END_OUTPOS, %eax ret setoutpos: pushl %ebp movl %esp, %ebp movl 8(%ebp), %ecx /*movl $UTBUFFERT, %edx movl END_OUTPOS, %edx*/ cmpl $0, T jb neg_sign /*movb %cl, (%edx) jmp end_setoutpos*/ cmpl $0, %ecx jb setoutpos_zero cmpl MAXPOS, %ecx jg setoutpos_max jmp end_setoutpos setoutpos_zero: movl $0, %ecx movl %ecx, END_OUTPOS jmp end_setoutpos setoutpos_max: movl MAXPOS, %ecx movl %ecx, END_OUTPOS jmp end_setoutpos neg_sign: xorl %ecx, %ecx movl '-', %ecx movb %cl, (%edx) end_setoutpos: movl %ecx, END_OUTPOS movl %ebp, %esp addl $4, %esp popl %ebp ret
So, the program asks for two numbers. Reads them, converts them and sums them together and prints it out. If I put in
314SPC555 the result should be: 314+555=869.
But I don't get this to work properly. When I run through the debugger everything works fine when reading 314 and converting it but next time when coming back and I want to read 555, it doesn't work. The position is 4, which is correct but the program starts to read 314 instead of 555. And I just can't figure out why? There is propably something fundamental in my understanding of how the buffer works that is missing here.
So, here is the part of the code that I'm talking about:
getinpos: movl START_INPOS, %ecx movl %ecx, %ebx getchar: movl $INBUFFERT, %ebx xorl %eax, %eax /*cmpb $45, (%ebx) je increase_charN */ getchar_loop: cmpb $32, (%ebx) je increase_char movsx (%ebx), %eax pushl %eax incl %ecx incl %ebx jmp getchar_loop increase_char: incl %ecx movl %ecx, END_INPOS decl %ecx
I let the INBUFFERT( which is declared as .skip 128) point to %ebx, and before that I have set the START_INPOS to 4. It reads 3 as character when starting to read the second number instead of 5. But why? What am i missing here?
Then another thing. I have to clear out the UTBUFFERT, since printing out Head will put this in UTBUFFERT. But how do I clear the UTBUFFERT? I am supposed to do that in Outimage.Now outimage looks like:
outimage: pushl $UTBUFFERT call puts addl $4, %esp ret
Should it look like this?
outimage: pushl $UTBUFFERT call puts addl $4, %esp movl $BUFSIZE movl $UTBUFFERT, %edx clearloop: movb $0, (%edx) incl %edx decl %ecx jnz clearloop ret
Can anyone please help me on these issues?
Anders


Sign In
Create Account

Back to top









