So basically I'm trying to read a string, increase a counter (in this case, %edx) until I read a \n, and then, going backwards to print it reversed.
This is my code:
.section .data
cadsal:
.asciz "Por favor ingrese su cadena:\n"
leer:
.asciz "%s"
salidafinal:
.asciz "La cadena introducida, invertida es:\n"
imp:
.asciz "%c\n"
.section .bss .comm cadena,50,1
.section .text
.globl _start
_start:
leal cadsal, %eax
pushl %eax
call printf
addl $4, %esp
leal cadena, %eax
pushl %eax
leal leer, %eax
pushl %eax
call scanf
addl $8, %esp
xorl %edx, %edx
Contar:
movb cadena(%edx), %al
incl %edx
cmpb $0, %al
jne Contar
leal salidafinal, %ecx
pushl %ecx
call printf
addl $4, %esp
addl $-2, %edx
Invertir:
movb cadena(%edx), %al
pushl %eax
leal imp, %ebx
pushl %ebx
call printf
addl $8, %esp
decl %edx
cmpl $0, %edx
jge Invertir
movl $1, %eax
int $0x80
I'm using the command -nostartfiles when compiling. It works, but when I run it, segmentation fault appears when entering in "Invertir". I need help to detect what's wrong in this code.
Thanks!
Your immediate problem is cmpb '\n', %al
which is missing the $
sign required in at&t syntax to make it an immediate. As it is, '\n'
is considered an address, and an invalid one at that. You should use cmpb $'\n', %al
.
However scanf
will not place '\n'
into your buffer at all, because %s
stops at whitespace. So you really want to be looking for a terminating zero byte instead, that is use cmpb $0, %al
. Or, if you really need to read a whole line, use fgets
instead.
If you fix that, you will run into the next problem which is that you have an incl %edx
between your cmp
and the jne
which will change the flags so you will not be branching on the result of the comparison but the increment. Solution: swap the cmp
and the incl
.
Yet another problem is that some registers, including %edx
, are caller-saved. As such they can be modified by called functions, and you do call printf
. You should push
/pop
around both of those to preserve the value.
Even after all of that, you probably won't see any output until you print a final \n
manually, due to buffering.
Note that if you intend to use C library, you should really not use -nostartfiles
. Instead, you should use entry point main
and assemble and link normally. Also, you should simply return from main
(or at most call exit
) and not use direct system call because that doesn't allow the C library to clean up properly. Incidentally, that would also flush the I/O buffers, so you would see the output even without an extra newline.
You should really learn to use a debugger.