Вызов getchar из сборки

Я пытаюсь написать простую тестовую программу на ассемблере, которая просто вызывает getchar и передает возвращаемое значение putchar. Мой текущий код выглядит так:

.global main
.text

main:
mov $12,%rbx
.head:
call getchar
mov %rax,%rcx
call putchar
dec %rbx
test %rbx,%rbx
jne .head
call exit

Программа скомпилирована с использованием gcc -o prog prog.s в Windows 10 с Cygwin (с сохранением приведенного выше кода на prog.s).

Я ожидаю, что это будет прочитано из стандартного ввода 12 раз (произвольно) и сразу же отправит 12 прочитанных символов в стандартный вывод. Другими словами, при запуске программы с консоли я ожидаю, что она будет ждать, пока что-то не будет введено в консоль и не будет нажата клавиша Enter. Вместо этого на самом деле происходит следующее: когда я запускаю его, он немедленно выводит 12, казалось бы, бессмысленных символов и завершает работу:

������������

В предыдущих программах, которые вызывали функцию C, которая использовала в себе getchar, затем выводила на печать символ чтения, а также результат для ferror(stdin). getchar, по-видимому, вернул -1, и флаг ошибки stdin был установлен, как только был вызван getchar. Почему это могло происходить? Тем более, что программа, написанная исключительно на C, может без проблем вызывать getchar.

Возможно ли, что вы действительно использовали подсистему Windows для Linux или что-то в этом роде, где соглашение о вызовах передает первый аргумент в RDI, а не в RCX? Может быть, попробовать еще и mov %eax, %edi? Однако это не объясняет немедленное возвращение getchar. Я удивлен, что call putchar связан в Windows, где имена символов C обычно получают подчеркивание в начале, например call _putchar. Используйте file prog, чтобы узнать, является ли это исполняемым файлом ELF64 (Linux) или Windows PE / COFF. Тем более, что вы называете его prog, а не prog.exe.

Peter Cordes 21.12.2018 02:50

Я использовал -o prog при компиляции, но он все еще сохранен на prog.exe, и file prog показывает, что это исполняемый файл PE32 +, x86-64, для MS-Windows.

user2649681 21.12.2018 02:53

На всякий случай добавьте -mconsole в командную строку gcc.

Jester 21.12.2018 02:55

Добавление -mconsole не повлияло на поведение или результат file prog.

user2649681 21.12.2018 02:56

Обратите внимание, что вы неправильно выравниваете стек и не настраиваете теневое пространство, как того требует соглашение о вызовах. Вставка subq $40, %rsp после main: заставляет его работать, используя wine, по крайней мере, на Linux.

Jester 21.12.2018 03:04

Почему 40-5 слов - это значение, которое нужно добавить в стек? Есть ли какое-то гарантированное выравнивание или несовпадение стека при запуске программы?

user2649681 21.12.2018 03:08

Вам нужно добавить 8 для выравнивания (поскольку CALL выталкивает еще 8 байтов). 32 предназначены для теневого пространства. См. Документацию по соглашению о вызовах. Это сработало?

Jester 21.12.2018 03:10

@Jester: Я заметил отсутствие выделения нового теневого пространства, но этот main не возвращается: он вызывает exit. Помимо выравнивания, можно позволить getchar наступать на основной адрес возврата и выше, если мы не собираемся возвращаться. Несоосность стека обычно вызывает сбой или отсутствие эффекта, но вполне вероятно, что getchar делает предположение о том, что будет указывать где где после AND. Хотя маловероятно.

Peter Cordes 21.12.2018 03:12

Выравнивание стека и настройка теневого пространства заставили его работать.

user2649681 21.12.2018 03:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
9
814
0

Другие вопросы по теме