2015-05-31 8 views
1

Так что в основном я пытаюсь прочитать строку, увеличиваю счетчик (в данном случае% edx), пока не прочитаю a \ n, а затем, возвращаясь назад, чтобы напечатать его в обратном порядке ,Реверсирование строки и ее печать в сборке IA32

Это мой код:

.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 

Я использую команду -nostartfiles при компиляции. Он работает, но когда я его запускаю, при входе в «Инвертировать» появляется ошибка сегментации. Мне нужна помощь, чтобы определить, что не так в этом коде.

Спасибо!

ответ

1

Ваша непосредственная проблема: cmpb '\n', %al, которому не хватает знака $, требуемого в & t синтаксис, чтобы сделать это незамедлительно. Как это, '\n' считается адресом, а недействительным. Вы должны использовать cmpb $'\n', %al.

Однако scanf не разместит '\n' в вашем буфере, потому что %s останавливается в пробеле. Таким образом, вы действительно хотите искать конечный нулевой байт, то есть использовать cmpb $0, %al. Или, если вам действительно нужно прочитать целую строку, используйте вместо этого fgets.

Если вы исправить это, вы столкнетесь с следующей проблемой, которая является то, что у вас есть incl %edx между вашим cmp и jne, которая изменит флаги, так что вы не будете разветвлением на результате сравнения, но приращения. Решение: замените cmp и incl.

Еще одна проблема заключается в том, что некоторые регистры, включая %edx, являются сохраненными. Таким образом, они могут быть изменены вызываемыми функциями, и вы делаете call printf. Вы должны push/pop вокруг обоих из них, чтобы сохранить значение.

Даже после всего этого вы, вероятно, не увидите никакого вывода, пока не распечатаете окончательный \n вручную из-за буферизации.

Обратите внимание, что если вы собираетесь использовать библиотеку C, вы действительно не должны использовать -nostartfiles. Вместо этого вы должны использовать точку входа main и собирать и связывать нормально. Кроме того, вы должны просто вернуться с main (или не более call exit) и не использовать прямой системный вызов, потому что это не позволяет корректно очистить библиотеку C. Кстати, это также приведет к сбросу буферов ввода-вывода, поэтому вы увидите вывод даже без дополнительной строки новой строки.

Вы должны научиться использовать отладчик.

+0

Эй! Спасибо за ответ. Извините, я все еще любитель на собрании. Что вы подразумеваете под этим: вы должны нажать/погладить оба из них, чтобы сохранить значение. Что мне делать? –

+0

'push% edx' перед' printf' (включая настройку аргумента) и 'pop% edx' после' add esp'. – Jester

+0

Сменил первый cmp и, в частности, «Contar» теперь работает нормально. Теперь я получаю ошибку сегментации в «Инвертире». Измененный addl $ -2,% edx, потому что contar заканчивается с% edx на один шаг вперед от $ 0 (конец строки). –

 Смежные вопросы

  • Нет связанных вопросов^_^