ПО, ЭВМ и АСУ из Таможенного Союза

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » Проект "Виртуальные машины" » Об эмуляторе Интел64 в Сказочной Колеснице


Об эмуляторе Интел64 в Сказочной Колеснице

Сообщений 1 страница 7 из 7

1

Вопросов больше, чем ответов

Сначала нужно описать, что входит в новую машину (регистры, стек, память, что там еще...) и представить это в виде структуры.
Потом, какая разрядность команды и как она кодируется.
Какое устройство программы с байт-кодом, из каких частей она состоит.
Как это все будет считываться и по каким переменным или массивам раскладываться.
Потом, либо писать кусок кода для каждой инструкции в лоб, либо делать макросы, чтобы сократить код.

В виртуальную машину Интел64,
которая сможет выполнить ассемблерную программу "здравствуй мир"

входят 5 регистров:
# регистр ФРЕЙМ (RBP) // не нужен, пока нет подпрограмм
# регистр ВЕРШИНА_СТЕКА (RSP) // не нужен, пока нет подпрограмм
регистр АККУМУЛЯТОР (RAX)
регистр ДАННЫЕ (RDX)
регистр АДРЕС_ИСТОЧНИК (RSI)
регистр АДРЕС_ПРИЁМНИК (RDI)
регистр АДРЕС_КОМАНДЫ (RIP) // тоже, в принципе, не нужен, но используется неявно

три команды:
ЗАГРУЖАЕМ константа, %регистр
КСОРИМ %регистр, %регистр
ПОБУЖДАЕМ

две константы имён системных фунукций:
ЗОВ_ВЕЩАТЬ
ЗОВ_ЗАВЕРШИТЬСЯ

и одна константа
СТДВЫХ

Разрядность регистров 64 бита.

Программа имеет формат ELF-файла.

Считываться всё это будет из файла, в память начиная с наименьшего адреса.

Код сократить можно не только при помощи макросов, но и за счёт использования подпрограмм.

Как кодируются команды:
команды кодируются последовательностями байтов переменной длины
(Лис пока не успел записать все 4 последовательности байтов для трёх команд и кода вызова операционной системы,
но работает над этим)

Отредактировано Лис (2023-03-11 21:35:10)

0

2

Зачем делать виртуальную машину?

Pavel Bibichenko написал(а):

Тут же просто напридумывали опкодов, реализовали из них всего 2, да и то неполно.

Команд будет уже четыре, поэтому в пресс-релизе можно будет сообщить об 200%-ном увеличении количества реализованных команд процессора.

0

3

Pavel Bibichenko написал(а):

Тут же просто напридумывали опкодов, реализовали из них всего 2, да и то неполно

У меня уже не две, а целых три. А с вариантами адресации уже 15.

Лис написал(а):

(Лис пока не успел записать все 4 последовательности байтов для трёх команд и кода вызова операционной системы,
но работатет на этим)

А у меня появилась идея, как приделать к "Сказочной колеснице" кроме треугольного колеса Евгения еще и квадратное колесо Лиса.
Поработаю над этим.

Отредактировано Евгений (2023-03-10 13:17:45)

0

4

Вот тут ещё Уткин хотел платформу Windows:
Машкод
а там другие системные вызовы, несмотря на то, что система команд Интел64.
в принципе, это тоже можно было бы организовать, например при помощи сборки через Cygwin и запуска в wine.

Лис написал(а):

работает над этим

Пять лет прошло. Люди за такое время ВУЗы заканчивают...

А я три ассемблерных команды странслировал:

0x48    0xc7    0xc0    0x01    0x00    0x00    0x00
//  mov     $1, %rax                # system call 1 is write

0x48    0xc7    0xc7    0x01    0x00    0x00    0x00
// mov     $1, %rdi                # file handle 1 is stdout

0x48    0xc7    0xc6    0xaf    0x16    0x40    0x00
// mov     $message, %rsi          # address of string to output

0x48    0xc7    0xc2    0x0d    0x00    0x00    0x00
// mov     $13, %rdx               # number of bytes

0x0f    0x05
// syscall                         # invoke operating system to do the write

0x48    0xc7    0xc0    0x3c    0x00    0x00    0x00
// mov     $60, %rax               # system call 60 is exit

0x48    0x31    0xff
// xor     %rdi, %rdi              # we want return code 0

0x0f    0x05
// syscall                          # invoke operating system to exit

Тут, конечно, есть подозрительные байты, над которыми надо подумать ещё.

Байты брал из gdb на том сайте:
https://www.onlinegdb.com/online_gcc_assembler

вводил команды
start
x/1xb $pc
step

Отредактировано Лис (2023-03-11 21:35:36)

0

5

Можно что-нибудь вроде

.data
.text
.global main
main:
# 0xe8    0x00    0x00    0x00    0x00
        call + (. + offset)
reentry:
offset = reentry - main
# 0x5e
        pop     %rsi
# 0x48    0x8d    0xb6    0x2b    0x00    0x00    0x00
        lea distance(%rsi), %rsi
        # write(1, message, 13)
        mov     $1, %rax                # system call 1 is write
        mov     $1, %rdi                # file handle 1 is stdout
#        mov     $message, %rsi          # address of string to output
        mov     $13, %rdx               # number of bytes
        syscall                         # invoke operating system to do the write

        # exit(0)
        mov     $60, %rax               # system call 60 is exit
        xor     %rdi, %rdi              # we want return code 0
        syscall                         # invoke operating system to exit
message:
        .ascii  "Hello, world\n"
distance = message - reentry

Вот здесь точно не нужен будет никакой линковщик и таблица адресов. Только заголовок ELF-файла.

А если ещё и файл будет неперемещаемый, то можно будет просто в заголовке указать, по какому адресу он будет грузиться.
И этот адрес вписать как константу.

ChatGPT
предлагает одну команду
# 0x48    0x8d    0x35    0x24    0x00    0x00    0x00
   lea message(%rip), %rsi
а не использовать стек для получения %RIP.

Код:
.text
.global main
main:
        # write(1, message, 13)
        lea       msg_start(%rip), %rsi
        mov     $msg_len, %rdx               # number of bytes
        mov     $1, %rdi                # file handle 1 is stdout
        mov     $1, %rax                # system call 1 is write
        syscall                         # invoke operating system to do the write

        # exit(0)
        mov     $60, %rax               # system call 60 is exit
        xor     %rdi, %rdi              # we want return code 0
        syscall                         # invoke operating system to exit
msg_start:
        .ascii  "Hello, world\n"
msg_len = . - msg_start

Отредактировано Лис (2023-03-11 22:36:21)

0

6

Так, надо собраться с духом и написать один сплошной файл, в котором будет и заголовок байтами и код.

Когда я использую линковщик ld,
https://sourceforge.net/p/app-emulation … ive-world/
у меня создаётся лишняя секция, и вырезать её аккуратно не получается.

Но байты там есть.

https://github.com/tchajed/minimal-elf/raw/main/elf.png

Предлагают вместо этого использовать
objcopy -O binary -j .text main.o a.out

На гитхабе есть для NASM:
https://github.com/ezeaguerre/linux-asm … r/main.asm
но я хочу во-первых, для GAS,
во-вторых как-то более прокомментированно? Или не хочу?

Ещё предлагают

$ as --64 main.S -o main.o
$ ld -Ttext 200000 --oformat binary main.o  -o a.out
$ objdump -D -b binary -m i386:x86-64 test.bin

Вот и на LOR в 2005-м году тоже - https://www.linux.org.ru/forum/development/898481

Отредактировано Лис (2023-03-12 03:04:56)

0

7

Вобщем, вот как-то так оно запускается:
https://sourceforge.net/p/app-emulation … rld/main.s

Раскладку по полям проверял на сайте
https://elfy.io/

Код:
$ hexdump a.out
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000010 0002 003e 0001 0000 0078 0040 0000 0000
0000020 0040 0000 0000 0000 0000 0000 0000 0000
0000030 0000 0000 0040 0038 0001 0000 0000 0000
0000040 0001 0000 0005 0000 0078 0000 0000 0000
0000050 0078 0040 0000 0000 0078 0040 0000 0000
0000060 00ac 0000 0000 0000 00ac 0000 0000 0000
0000070 0008 0000 0000 0000 8d48 2335 0000 4800
0000080 c2c7 000a 0000 c748 01c7 0000 4800 c0c7
0000090 0001 0000 050f c748 3cc0 0000 4800 ff31
00000a0 050f 6152 2077 6f77 6c72 0a64          

Size of 'a.out' is 172 bytes
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header

Elf file type is EXEC (Executable file)
Entry point 0x400078
There is 1 program header, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000078 0x0000000000400078 0x0000000000400078 0x0000ac 0x0000ac R E 0x8

a.out:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x0000000000400078

Отредактировано Лис (2023-03-12 14:13:06)

0


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » Проект "Виртуальные машины" » Об эмуляторе Интел64 в Сказочной Колеснице