sub rsp, <size>
, чтобы зарезервировать место в стеке перед тем, как прикасаться к нему, если вы используете более 128 байтов ниже RSP.
При сбое посмотрите на память вашего процессакарта.Возможно, вы используете память до уровня ниже RSP, чтобы ядро не увеличивало отображение стека, и, таким образом, это просто обычный доступ к неотображенной странице = ошибка неверной страницы => ядро предоставляет SIGSEGV.
(только для ABIопределяет 128-байтовую красную зону, но на практике единственное, что может заглушить эту память, - это обработчик сигналов (который вы не установили) или GDB, выполняющий print some_func()
с использованием стека вашей программы для вызова функции в вашей программе.)
Обычно Linux очень хочет увеличить отображение стека, не затрагивая промежуточные страницы, но, очевидно, проверяет значение RSP.Обычно вы перемещаете RSP вместо того, чтобы просто использовать память намного ниже указателя стека (потому что нет гарантии, что это безопасно).См. Как выделяется стековая память при использовании инструкций «push» или «sub» x86?
Еще один дубликат: Какое исключение может быть сгенерировано при вычитании регистра ESP или RSP?(увеличение стека) , где было достаточно использования sub rsp, 5555555
до касания новой стековой памяти.
Стек ASLR может запускать RSP в разных местах относительно границы страницы , поэтому вы можетепросто сходит с рук иногда. Linux изначально отображает 132 КБ стекового пространства , и это включает пространство для среды и аргументы в стеке при входе в _start
.Ваш 128 кБ очень близок к этому, поэтому вполне вероятно, что он иногда работает случайным образом.
И, кстати, есть нулевая причина для фактического копирования памяти в пространстве пользователя, особенно не 1 байт за раз.Просто передайте тот же адрес на write
.
Или, по крайней мере, отфильтруйте на месте, если это возможно, чтобы уменьшить объем кэша.
Кроме того, обычный способ загрузки байта - это movzx eax, byte [mem]
.Используйте mov al, [mem]
только если вы хотите объединить со старым значением RAX.На некоторых процессорах mov
до al
имеет ложную зависимость от старого значения, которое можно разорвать, записав полный регистр.
И, кстати, если ваша программа всегда использует это пространство, вы можете статически распределить его в BSS.Это делает возможным более эффективную индексированную адресацию, если вы решите собрать исполняемый файл, зависящий от позиции (не PIE).