hola tengo un problema, estoy tratando de aprender algo de las syscalls de linux con asm pero tengo un problema, mi codigo no funciona, el comportamiento es el siguiente.
se supone que pide un texto e imprime su longitud pero sucede:
pide texto, falla de segmentacion
la consola toma lo que tecle y me dice como que si lo hubiera escrito como un comando ejemplo:
si en el programa pongo hola
no me imprime nada y despues la terminal me dice
bash: ola comando no encontrado
mi code es el siguiente
include '/home/nyox/include/linux.inc'
format ELF executable
entry start
segment readable executable
start:
mov eax,SYS_READ
mov ebx, STDIN
mov ecx,texto
mov edx,size
int 0x80
push texto
call strlen
push eax
push numtexto
call itoa
push numtexto
call strlen
mov edx,eax
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, numtexto
int 0x80
mov eax, SYS_EXIT
xor ebx,ebx
int 0x80
strlen:
push edi
xor ecx,ecx
mov edi, [esp + 8]
not ecx
xor eax,eax
cld
repne scasb
not ecx
pop edi
add eax,ecx
dec eax
retn 4
strrev:
push ebp
mov ebp,esp
push edi
mov edi,[ebp + 8]
push edi
call strlen
xor ecx,ecx
dec eax
jmp LL1
LL0:
dec eax
inc ecx
cmp ecx,eax
jge LL2
LL1:
mov dl,byte[edi + ecx]
xchg byte[edi + eax],dl
mov byte[edi + ecx],dl
jmp LL0
LL2:
pop edi
pop ebp
retn 4
itoa:
push ebp
mov ebp,esp
pushad
mov edi,[ebp + 8]
mov eax,[ebp + 12]
mov ebx,10
L@@1:
xor edx,edx
div ebx
xchg eax,edx
or eax,48
stosb
mov eax,edx
cmp eax,0
jnz L@@1
inc edi
mov byte[edi],al
push dword[ebp + 8]
call strrev
popad
pop ebp
retn 8
numtexto db 5 dup(0)
texto db 10 dup(0)
size dd 9
SYS_WRITE = 4
SYS_READ = 3
STDIN = 0
STDOUT = 1
el codigo rula perfectamente en win aunque no es lo mismo porque uso printf y scanf asi que supongo que mi error esta en el uso de las syscalls a ver si me pueden echar una mano
el code en win es
format PE console
entry start
include 'c:\fasm\include\win32ax.inc'
.code
start:
invoke scanf,"%s",texto
push texto
call strlen
push eax
push numtexto
call itoa
push numtexto
call strlen
invoke printf,numtexto
leave
ret
strlen:
push edi
xor ecx,ecx
mov edi, [esp + 8]
not ecx
xor eax,eax
cld
repne scasb
not ecx
pop edi
add eax,ecx
dec eax
retn 4
strrev:
push ebp
mov ebp,esp
push edi
mov edi,[ebp + 8]
push edi
call strlen
xor ecx,ecx
dec eax
jmp LL1
LL0:
dec eax
inc ecx
cmp ecx,eax
jge LL2
LL1:
mov dl,byte[edi + ecx]
xchg byte[edi + eax],dl
mov byte[edi + ecx],dl
jmp LL0
LL2:
pop edi
pop ebp
retn 4
itoa:
push ebp
mov ebp,esp
pushad
mov edi,[ebp + 8]
mov eax,[ebp + 12]
mov ebx,10
L@@1:
xor edx,edx
div ebx
xchg eax,edx
or eax,48
stosb
mov eax,edx
cmp eax,0
jnz L@@1
inc edi
mov byte[edi],al
push dword[ebp + 8]
call strrev
popad
pop ebp
retn 8
section '.data' data readable writeable
numtexto db 5 dup(0)
texto db 10 dup(0)
size dd 9
section '.idata' import data readable
library msvc,'msvcrt.dll'
import msvc,printf,'printf',scanf,'scanf'
no cambia mucho solo el uso de entrada y salida
gracias de antemano
¿En que instruccion exactamente da el fallo? Podes usar gdb para depurarlo y averiguar esto. Deberias comprobar que el sys_read devuelva un valor de retorno que indique la finalizacion exitosa de la funcion.
¿No deberian estar los datos en otra sección? Algo como:
segment readable writeable
numtexto db 5 dup(0)
texto db 10 dup(0)
size dd 9
Luego lo veo bien ( Cuando me pase a linux que estoy en win ) , pero veo un error que es
segment readable executable
Hay no le das la propiedad de writeable para poder escribir en las variables.
perfecto ese era el error ahora si me funciona bien, era lo de writeable, me funciona de ambas maneras poniendo un nuevo segmento con readable writeable o asignandole la propiedad de escritura al segmento actual. Que error mas estupido :laugh:
gracias EI y yst no se me habia ocurrido lo del segment
saludos
P.D Creo que SYS_READ incluye el retorno en la cadena porque me aparece con una longitud un caracter mas largo de lo que es
Toma documentación sobre las syscalls
http://sourceforge.net/project/downloading.php?group_id=173983&filename=lscr-160307.tar.gz&a=60287788
gracias por la documentacion, estan muy buenos los ejemplos y estan en fasm ;-)