Не могу понять, что мне нужно положить sh в стек перед вызовом `_getch` в FASM - PullRequest
1 голос
/ 21 февраля 2020

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

format ELF

section '.data' writeable
    msg db 'Hello, world of Flat ASM!',  0Dh, 0Ah, 00h ; terminate with null string
    buffer rb 20
    inp_buf_size rw 1
    pkey db 'Press any key to exit ...', 0h
    formatStr db "%s", 0

section '.text' executable
public _main
extrn _printf
extrn _getch
extrn _getche
_main:
    mov ebp, esp; for correct debugging
    push msg ; push message onto the stack
    push formatStr ; push formatter onto the stack
    call _printf ; call the printf method to print the message
    add esp, 8 ; clean up
    xor eax, eax
    ; press any key to exit
    mov ebp, esp; for correct debugging
    push pkey ; push message onto the stack
    push formatStr ; push formatter onto the stack
    call _printf ; call the printf method to print the message
    add esp, 8
    xor eax, eax

    ; get input here, using getch or getche (how? What must be pushed)
    ; mov ebp, esp; for correct debugging
    ; push buffer
    ; call _getch
    ; add esp, 8
    ; xor eax, eax

    ret

Печать кода «Hello, world ...» и «Press any key ...» работает, как и ожидалось. Я застрял на том, как я go заставляю программу ждать / читать один символ в буфер, используя _getch. (Что, если что, я должен положить sh в стек перед вызовом _getch?) Я попытался переместить значения в ah и использовать прерывания, но это заставляет программу обрабатывать sh.

  • ОС: Windows 10 x86_64
  • Язык ассемблера: FASM (в комплекте с SASM) - $SOURCE$ $PROGRAM.OBJ$ -s $LSTOUTPUT$
  • ** Режим: ** x86
  • Опции компоновщика: $PROGRAM.OBJ$ $MACRO.OBJ$ -g -o $PROGRAM$ -m32

Ответы [ 2 ]

0 голосов
/ 22 февраля 2020

На самом деле я пытался выяснить, как заставить SASM вести себя на Windows, когда я нашел ваш вопрос, после того, как я написал другой ответ, я наткнулся на способ, которым он может использовать собственный синтаксис Windows FASM. , В параметрах сборки установите флажок «Отключить связывание» и измените параметр $PROGRAM.OBJ$ «Параметры сборки» на $PROGRAM$. Это заставит его использовать Windows FASM.exe для сборки вашего exe-файла и пропустить создание объекта в стиле Linux и соединение g cc.

Большим минусом этого является то, что отладчик нет больше работает, что является убийцей сделки.

Чтобы показать, как выглядит Windows код FASM, вот мой привет мир:

format PE console
entry _main
include '%fasm_inc%/win32a.inc'

section '.data' data readable

hello db 'Hello world!', 0

section '.text' code readable executable

_main:
    invoke _printf, hello
    invoke _getchar
    push eax
    invoke _putchar
    invoke _ExitProcess, 0

section '.idata' import data readable

library kernel32, 'kernel32.dll',\
    msvcrt, 'msvcrt.dll'

import kernel32,\
        _ExitProcess, 'ExitProcess'
import msvcrt,\
        _printf, 'printf',\
        _getchar, 'getchar',\
        _putchar, 'putchar'

Я добавил _putchar, чтобы показать, что _getchar использует текст в поле ввода, и SASM не ожидает ввода пользователя.

0 голосов
/ 22 февраля 2020

Здесь происходит несколько вещей format ELF говорит FASM создать объектный файл Linux. Что немного странно, потому что вы бежите Windows. Но то, что заставляет это работать, - то, что SASM использует версию MinGW набора инструментов Linux g cc для создания исполняемого файла. Это означает, что вы можете написать некоторую Linux сборку, но не все может иметь синтаксис Linux.

Другая проблема заключается в том, что getch не является POSIX, поэтому может вызывать проблемы, используйте getchar.

И, наконец, windows не выходит из программ, используя возвращаемые значения в EAX. Из-за этого

xor eax, eax
ret

часть будет зависать в Windows. Безопасный способ сделать это - call _ExitProcess передать его в стеке.

Похоже, что SASM ожидает ввода любого ввода в поле ввода заранее, и из-за этого не ожидает _getchar , Я оставил это, чтобы показать, как это будет работать, если SASM не сделает этого. Выполнение аналогичного кода, собранного напрямую с использованием FASM, работает, как и ожидалось.

Собрав все это вместе, мы получим следующее:

format ELF

section '.data' writeable
    msg db 'Hello, world of Flat ASM!',  0Dh, 0Ah, 00h
    pkey db 'Press any key to exit ...', 0h
    formatStr db "%s", 0

public _main
extrn _printf
extrn _getchar
extrn _ExitProcess

section '.text' executable

_main:
    push msg 
    push formatStr
    call _printf

    push pkey
    push formatStr
    call _printf

    call _getchar
    push 0
    call _ExitProcess

Я удалил код стека для простоты, поскольку это всего лишь привет мир.

...