#string #assembly #x86 #stack #calling-convention
#строка #сборка #x86 #стек #соглашение о вызове
Вопрос:
Я пытаюсь передать строку процедуре, поместив строку в стек. Я знаю, что аргументы командной строки аналогичным образом помещаются в стек, поэтому, пытаясь их понять, я решил создать надуманный прототип, который помещает непрерывный массив символов ASCI в стек и обращается к строке с помощью вызываемой процедуры. Однако при запуске кода я могу получить доступ только к одному символу, а не к массиву, через printf
строку формата %c
. При использовании спецификатора строки формата %s
я получаю ошибку сегментации. Возможно, я неправильно понимаю, как работает адресация памяти и как правильно обращаться к данным esp
, на которые указывает. Вот моя попытка:
; assemble and link with:
; nasm -f elf test.asm amp;amp; gcc -m32 -o test test.o
section .text
global main
extern printf
some_proc:
push ebp
mov ebp, esp
mov eax, [ebp 8]
push eax
push format_str
call printf
mov esp, ebp ; Deallocate local variables
pop ebp ; Restore the caller’s base pointer value
ret 4
main:
push 0x00796568 ; hey
call some_proc
mov eax, 1
int 0x80
section .data
format_str db `%sn` ; <- doesn't work
;format_str db `%cn` <- works
Этот код выводит только первый символ ‘h’, а не весь непрерывный массив строк hey
. Какие изменения мне нужно внести в этот код, чтобы выполнить правильную логику / вывод?
Ожидаемый стандартный вывод:
hey
Фактический стандартный вывод:
Segmentation Fault
Если вы видите какие-либо ошибки в моем коде, пожалуйста, сообщите мне, я новичок в сборке.
Комментарии:
1.
%s
Директива ожидает, что адрес строки будет помещен в стек, а не сама строка. Исправьте свой код, изменивmov eax, [ebp 8]
lea eax, [ebp 8]
вместо этого на push адрес строки. Обратите внимание, что обычно вы передаете строки функциям, передавая их адреса, а не помещая их в стек.2. Обычно вы не указываете ESP на массив, если только вы не злоупотребляете
pop
чтением массива с лучшей производительностью, чемlodsd
или что-то в этом роде, например, в Extreme Fibonacci (code golf оптимизирован для размера и немного для скорости). Но обычно это не имеет смысла для байтов.