LINUX.ORG.RU

Assembler Gas непонятное для меня поведение программы

 


0

1

здрасьте здрасте люди добрые

объясните кто знает, почему программа не вылетает с ошибкой а уходит в цикл


.section .bss
out:
.space 8

.section .data

frt: "%d"

.section .text
.global main
main:
  lea out, %rsi
  lea frt(%rip), %rdi
  mov $0, %rax
  call scanf
  mov $0, %rax

  mov out, %rsi
  lea ft(%rip), %rdi  // только тут заметил значение RIP, как надпись покойся с миром.
   mov $0, %rax
  call printf
   mov $0, %rax

  

если добавить в конец ret, то что он снимет со стека? адрес следующей команды за scanf или за printf?

что тут произойдет? scanf положит на стек адрес следующей команды, а это будет mov $0, %rax. дальше все попорядку и когда дойдет до printf то на стек ляжет адрес команды следующей за printf.

а что потом? можете объяснить, как это все будет разматываться?



Последнее исправление: Assembler (всего исправлений: 1)
Ответ на: комментарий от alysnix

стопэ. нам видимо надо вместе в школу. ret не поможет.

ret-это команда, которая снимает со стека , с его верха адрес следующей команды за call.

последник call в моем коде это call printf. за ним ничего не идет. если я посалю ret то по вашей логике я снял бы со стека следующей команды за printf а за ней как раз идет ret, который идет на стек и снимает адрес с вершины стека.

чтобы все правильно отработало значит нужна такая последовательность


leave
ret
тогда call printf положит на стек адрес команды
leave
[/cod]
 а ret его снимет со стека и передаст управление.



но программа работает и без leave только с ret. значит не вы ни я неправы.  

блин, хоть бы один шарящий зашел. 

Assembler
() автор топика
Ответ на: комментарий от Assembler

почитайте уже, кто кладет на стек адрес возврата, и кто берет это адрес. я вам уже стописят раз сказал.

кладет на стек адрес возврата команда call!!! читайте описание команды а забирает его со стека и возвращается команда ret!!! тоже читайте описание.

ставьте ret в конце кода, на стеке в данный момент находится адрес возврата в функцию, которая вызвала ваш main. ваш main ВЫЗВАЛИ командой call! вот к вызывавшему и надо выйти, чтобы завершить вашу программу.

формирование пролога и эпилога функции у интела это команды enter, leave. пролог и эпилог вам в данном не нужны. они нужны если делается фрейм на стеке для переменных и/или параметров вашей функции. раз у вас нет enter, то и leave вам не нужен.

у вас в голове нереальная каша, вы путаете пролог эпилог с адресом возврата

alysnix ★★★
()
Ответ на: комментарий от alysnix

алексей, вы не правы.

/////

////
////

call scanf; на стеке адрес возврата команды, что идет за call scanf

////
///
call printf на вершине стека адрес возрвата что ниже call printf, а это ret
///
/////
ret; cнимет со стека свой адрес.


leave не нуждается в enter. вы просто читаете гугл и не имеете собственных знаний. очень жаль. еще одним невежей на форуме стало больше. а до меня раньше доходили слухи, что данный ресурс славится высококвалифицированными специалистами. мне говорили что тут почти все боги в программировании. вобщем ждем богов. может снизойдут.

Assembler
() автор топика
Ответ на: комментарий от Assembler

блин. это ж надо так морочиться. call положил на стек адрес возврата. а забрала его оттуда команда ret, что находится в конце ВЫЗВАННОЙ функции. ОНА В КОНЦЕ ВЫЗВАННОЙ ФУНКЦИИ, той которую вы вызвали. в данном случае scanf, там внутри scanf, есть ret. если б его там не было, вы бы не вернулись в свой main. но поскольку вы вернулись, адреса возврата на стеке уже нет, потому что исполнилась команда ret, вытолкнула адрес со стека, перешла по нему - то есть возврат произошел.

А этот ret, который вы все не можете написать тут, и который нужен, он для возврата в функцию что вызвала main. ваш main тоже вызвали, и ему нужен свой ret, чтобы main завершился.

alysnix ★★★
()
Ответ на: комментарий от alysnix

алеша, ты говоришь вещи, похожие на правду. возможно, что ты станешь главным помощником на этом форуме для модераторов

Assembler
() автор топика
Ответ на: комментарий от Assembler

Ну так если у тебя слинковано без –no-stdlib, то и main вызывается и возврат имеет. Вообще управление на старте передаётся _start, которая делает подготовку и потом зовёт main. А после main, её возврат используется в sys_exit.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.