Может кто-нибудь помочь мне разобраться в этом коде сборки?
24 бит для буфера?но что такое rsp?
rsp
- это указатель стека.Стек - это некоторая область в памяти, используемая для временного хранения данных функциями.На многих процессорах (включая x86) инструкция call
также сохраняет адрес инструкции, которая должна быть выполнена в стеке после инструкции ret
или retq
.
На процессорах x86 *Регистр 1013 * (32-разрядный: esp
) содержит адрес.Память перед этим адресом свободна, память по этому адресу и после того, как этот адрес используется.
Если вам требуется 100 байт временной памяти, вы вычитаете 100 из регистра rsp
;тем самым вы указываете, что эти 100 байт памяти используются (вашим кодом).Как только вам больше не понадобится память, вы восстанавливаете старое значение rsp
.
, поскольку retq
предполагает, что rsp
указывает на память, в которой call
хранит адрес,Вы должны восстановить старое значение rsp
, прежде чем выполнить retq
.
, не уверенный в том, что gets
do
gets
является функциейпредназначен для программирования на С.Он читает в одной строке текста (например, с клавиатуры).В вашем случае строка записывается в стек.В отличие от fgets
эта функция будет не проверять, достаточно ли места в памяти!
Если длина прочитанной строки превышает 24 байта, функция gets
перезапишет данные впамять, которая «использовалась» до инструкции sub $0x18, %rsp
.
И, как я уже писал, адрес, записанный call
и прочитанный retq
, хранится там!
InДругими словами: если строка, считанная с помощью gets
, слишком длинная, адрес, записанный с помощью call
, будет перезаписан, и инструкция retq
не вернется к вызывающей функции, но перейдет к некоторому неправильному адресу в памяти.
(надеюсь, это ответит на вопрос 2.)
Я думал, что мы уже вернулись
xchg %ax %ax
на самом деле не инструкция здесь, нопросто фиктивные данные.Он вставляется некоторыми компиляторами, потому что эти компиляторы всегда генерируют функции, кратные (например) двум байтам.
, но я запутался, что за второй столбец, например, в 1-й строке мы имеем1 48 38 ec
Это байты (в шестнадцатеричном формате) в ОЗУ, которые представляют инструкции ассемблера в 3-м столбце.
Пример: шестнадцатеричные байты 48 38 ec
в ОЗУ будет интерпретироваться ЦП как sub $0x18, %rsp
.
(Обратите также внимание на комментарий tum_: данные, показанные в вашем примере, явно неверны: 48 38 ec
, очевидно, не байты, представляющие инструкцию sub $0x18, %rsp
.)