Укажите esp на массив символов

#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 оптимизирован для размера и немного для скорости). Но обычно это не имеет смысла для байтов.