1 Replies - 1081 Views - Last Post: 05 February 2012 - 11:08 AM

Topic Sponsor:

#1 john32443  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 04-February 12

Segmentation error

Posted 04 February 2012 - 12:37 PM

Hey guys, Im writing a code to turn an integer into a sting. The problem is I'm getting this pesky segmentation error, I tried valgrind and gdb. If you guys have any ideas, that will be great!
%include "asm_io.inc"

;
; initialized data is put in the .data segment
;
segment .data
;
; 
;
; uninitialized data is put in the .bss segment
;
segment .bss
;	
	
	obuffer resd    20      		 ; Defines a buffer of size 20 double words to hold the output
	ibuffer resd	20	 		; Defines a buffer of size 20 bytes to hold the input
	
segment .text
	global int2string
int2string:
	enter 0,0
	pusha
	
	mov	 eax, [ebp+8]                  	 ; Moves input integer in eax		
	mov 	 ebx, 10			 ; Puts 10 in ebx to be used as a divisor  
	mov	 ecx, 0				 ; Intializes ecx
	mov      edx, 0		        	 ; Intializes edx
	
	mov	ecx, ibuffer                     ; Makes ecx a pointer to ibuffer 
	


	while :
	
	cmp	eax, 0       				; Tells compalier to check eax for jump condition	

	jz end_while		                      	; exit if eax equals zero, therefore there is no quotient

	div 	ebx		             	        ; Divides the input integer by 10
	add edx, 48            				; Adds 48 to the remainder to turn it into ASCII code
	mov [ecx], edx					; Moves the remainder into the buffer
	mov edx, 0				      	; Clears the remainder	
	inc 	ecx                     	      	; increments the buffer
	
	jmp 	while	
	
	end_while:
	
	mov edx, 0					;Clears edx
	mov edx,obuffer					; Makes a pointer to obuffer in edx
	mov ebx, 0

	whilelp :

	cmp ecx, 0      				; Tells compilier to check if ecx=0 for jump condition	
	
	jz end_whilelp		  		        ; exit if ecx=0
	
	mov ebx, [ibuffer]				; Moves the value of ibuffer into ebx
	mov [obuffer], ebx				; puts the value of ebx into the output buffer
	inc edx                                         ; Increments obuffer
	dec ecx						; Decrements ibuffer
	jmp	whilelp
	 
	end_whilelp :

	
	mov eax, obuffer	         		; puts the address of obuffer into eax 	 

	popa
        leave                     
 ret


VALGRIND ERROR MESSAGE:

Quote

=6505== Memcheck, a memory error detector
==6505== Copyright © 2002-2010, and GNU GPL'd, by Julian Seward et al.
==6505== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==6505== Command: ./p
==6505==
Enter a number: 21
vex x86->IR: unhandled instruction bytes: 0xC8 0x0 0x0 0x0
==6505== valgrind: Unrecognised instruction at address 0x8048520.
==6505== Your program just tried to execute an instruction that Valgrind
==6505== did not recognise. There are two possible reasons for this.
==6505== 1. Your program has a bug and erroneously jumped to a non-code
==6505== location. If you are running Memcheck and you just saw a
==6505== warning about a bad jump, it's probably your program's fault.
==6505== 2. The instruction is legitimate but Valgrind doesn't handle it,
==6505== i.e. it's Valgrind's fault. If you think this is the case or
==6505== you are not sure, please let us know and we'll try to fix it.
==6505== Either way, Valgrind will now raise a SIGILL signal which will
==6505== probably kill your program.
==6505==
==6505== Process terminating with default action of signal 4 (SIGILL)
==6505== Illegal opcode at address 0x8048520
==6505== at 0x8048520: ??? (in /home/john/Desktop/Assignment 2/p)
==6505== by 0x405E112: (below main) (libc-start.c:226)
==6505==
==6505== HEAP SUMMARY:
==6505== in use at exit: 0 bytes in 0 blocks
==6505== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==6505==
==6505== All heap blocks were freed -- no leaks are possible
==6505==
==6505== For counts of detected and suppressed errors, rerun with: -v
==6505== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6)
Illegal instruction

GDB:
Program received signal SIGSEGV, Segmentation fault.
0xb7e8e410 in _IO_vfprintf_internal (s=Cannot access memory at address 0xffffffff
) at vfprintf.c:1620
1620 vfprintf.c: No such file or directory.
in vfprintf.c



C Code:
#include <stdio.h>
//static char buffer [20];
//char * int2string(int i)


int main ()
{
int i;
char *str;
/* enter number from the keyboard */
printf ("Enter a number: ");
scanf ("%d",&i);
/* convert integer to string */
str = int2string(i);
/* output the string representation */
printf ("Number as string is: %s\n",str);
return 0;
}


I also tried using register dumps to figure out the variable in address of the memory problem as given by valgrind, but no luck.

This post has been edited by GunnerInc: 05 February 2012 - 10:26 AM
Reason for edit:: Added code tags


Is This A Good Question/Topic? 0
  • +

Replies To: Segmentation error

#2 GunnerInc  Icon User is online

  • "Hurry up and wait"
  • member icon

Reputation: 314
  • View blog
  • Posts: 902
  • Joined: 28-March 11

Re: Segmentation error

Posted 05 February 2012 - 11:08 AM

A few things are wrong:
1. you are moving the address of the buffer into eax then you are restoring the pushed registers so that address goes POOOOOOF!

2. you are pusing 1 parameter onto the stack but only using only a ret you must add the size of total parameters pushed or the stack will not be correct.

So, that being said this is wrong:
68	    mov eax, obuffer                    ; puts the address of obuffer into eax   
69	 
70	    popa
71	        leave                     
72	 ret

It should be:
    popa
    mov     eax, obuffer   ;puts the address of obuffer into eax 	 
    leave                     
    ret     4 ; or you can do ret 4 * NUMOFPARAMS

With ret 4:
PrintDec esp
    push    24
    call    Int2String
PrintDec esp

Quote

esp = 1638252
esp = 1638252

See esp is the same after the call. Now esp with out a ret 4:

Quote

esp = 1638252
esp = 1638248


Works fine for me, after fixing those problems
    push    24
    call    Int2String
    
    xor     ebx, ebx
    push    ebx
    push    ebx
    push    eax
    push    ebx
    call    MessageBoxA
    
    push    ebx
    call    ExitProcess


We can clean up your code a bit though.
1. You don't have to use pusha/popa unless you need to save all registers. The only registers that you must save (really only when you are interacting with the OS) are esi, edi, ebx, ebp, and esp

2. You are "Initializing" a register by moving zero into it then moving an address into it, don't have to "zero" it out first, if you have data in a register then move something else into it, the new data overwrites the previous data.
	mov	 ecx, 0				 ; Intializes ecx
	mov  edx, 0		        	 ; Intializes edx
	mov	ecx, offset ibuffer                     ; Makes ecx a pointer to ibuffer 

mov ecx, 0 is unnecessary. You are zeroing out edx for division right? There is a better way - xor edx, edx

This post has been edited by GunnerInc: 05 February 2012 - 11:40 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1