Я пытаюсь изучить некоторые очень простые ASM, чтобы помочь мне с чтением вывода gdb, выясняющего материал. Я слежу за несколькими учебниками в Интернете и сталкиваюсь с чем-то, что я не могу понять, как это сделать.Stack-based string IO с asm - что я делаю неправильно?
В следующем учебном пособии (http://programminggroundup.blogspot.fr/2007/01/programming-from-ground-up.html) рассказывается о строке IO в главе 5. Он использует сегмент .bss, чтобы объявить массив длиной 500 для ввода. Я могу заставить это работать без проблем. Тем не менее, теперь я пытаюсь получить массив в стеке, а не в сегменте .bss (который для меня похож на «глобальную память»).
Проблема в том, что я не могу понять, что я делаю неправильно. Насколько я могу видеть здесь, я переместил 64-байтовый раздел в стек, который я пытаюсь использовать для хранения ввода, а затем выводю его. Код не является ядром или иным образом не экспонируется, но когда я запускаю его и набираю «Hello» (без кавычек), тогда результат будет «ello», написанный в следующей командной строке. За ним следует возврат линии, поэтому «ello» немедленно выполняется по окончании программы.
[email protected]:~/folderomitted>./basic_io
Hello
[email protected]:~/folderomitted>ello
Насколько я могу видеть здесь, я пишу в стек. Я бы ожидал, что мне не нужно его обнулять, так как вход должен правильно переписывать содержимое. Я что-то здесь безумно ошибаюсь?
Это система unix IA-64 с газом. Кроме того, если я делаю вещи, которые действительно тупые (не только связанные с проблемой, которые у меня есть), скажите, пожалуйста!
.section .text
.globl _start
_start:
pushq %rbp # Store the original base pointer on the stack
mov %rsp, %rbp # The new base pointer is targeting the start of the stack
sub $64, %rsp # Move the stack pointer down by 64 bytes, thus saying we have 64 bytes to play with
mov %rsp, %rcx # Pass the content of the stack pointer to rcx, for the system call
mov $64, %rdx # Store the length of the buffer
mov $3, %rax # State that we want to use system_read
mov $0, %rbx # Select the handler (STDIN)
int $0x80 # invoke
mov $4, %rax # system_write
mov $1, %rbx # STDOUT
mov $64, %rdx # length of buffer
mov %rsp, %rcx # location of the buffer on the stack
int $0x80 # invoke
mov %rbp, %rsp # Restore the stack pointer to the original location
popq %rbp # pop the base pointer off the stack
mov $1, %rax # sys_exit
mov $0, %rbx # return code
int $0x80 # invoke
Поскольку это 64-разрядный код, вы можете переключиться с использования устаревших системных вызовов ('int 0x80') на использование команды' syscall'. Обратите внимание, что регистры, используемые для аргументов, будут отличаться (см. [Эта страница] (http://esec-lab.sogeti.com/post/2011/07/05/Linux-syscall -ABI)), и так будут перечислены столбцы (см. [unistd_64.h] (http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/asm-x86/unistd_64.h?v=2.6.25)) , – Michael