Вопрос по x86, nasm, assembly – Загрузка программ в ОЗУ и их выполнение NASM 16b

9

Я отчаянно нуждаюсь в решении этой проблемы. Я пытаюсь разработать ассемблерный код, позволяющий мне загружать и выполнять (путем ввода пользователя) 2 другие ассемблерные программы .EXE. У меня две проблемы:

Кажется, я не могу назначить путь к действительному регистру (или, возможно, неверный синтаксис)

Мне нужно иметь возможность выполнить другую программу после того, как первая (может быть любая) начала свое выполнение.

Вот что у меня есть:

<code>mov ax,cs ; moving code segment to data segment
mov ds,ax

mov ah,1h ; here I read from keyboard
int 21h
mov dl,al

cmp al,'1' ; if 1 jump to LOADRUN1 
JE LOADRUN1 

cmp al,'2' ; if 2 jump to LOADRUN2 
JE LOADRUN2

LOADRUN1:
    MOV AH,4BH
    MOV AL,00
    LEA DX,[PROGNAME1] ; Not sure if it works
    INT 21H


LOADRUN2:
    MOV AH,4BH
    MOV AL,00
    LEA DX,[PROGNAME2] ; Not sure if it works
    INT 21H

; Here I define the bytes containing the pathnames
PROGNAME1 db 'C:\Users\Usuario\NASM\Adding.exe',0 
PROGNAME2 db 'C:\Users\Usuario\NASM\Substracting.exe',0
</code>

Я просто не знаю, как запустить другую программу путем ввода в родительскую программу после того, как она уже выполняется.

Заранее спасибо за вашу помощь! Любую дополнительную информацию я с радостью предоставлю.

Это не оверлей. Я использую NASM 16 бит, Windows 7 32 бит.
ДОС int 21h) API - это устаревшее, неэффективное, в значительной степени неиспользуемое и нежелательное программное обеспечение, которое больше не должно использоваться. Тыабсолютн уверен, что тебе нужно его использовать? Daniel Kamil Kozar
Мне действительно нужна помощь, чтобы получить всю свою репутацию в качестве награды. Jean Carlos Suárez Marranzini
@ DanielKozar Да, конечно. В противном случае я бы не отдал свою репутацию. Мне действительно нужна помощь. Jean Carlos Suárez Marranzini
@ DanielKozar Не могли бы вы представить решение этой проблемы на основе требований, которые я написал? Это сделало бы мой день. Заранее спасибо Jean Carlos Suárez Marranzini

Ваш Ответ

1   ответ
7

так просто, как я надеялся, так что держитесь за свое место (места).

Во-первых, вам нужно осознать (как бы это ни звучало абстрактно), что DOS является однопользовательской, не многозадачной системой. В данном конкретном случае это означает, что у вас не может быть двух процессов, запущенных одновременно. Вынужн чтобы дождаться завершения одного процесса, прежде чем переходить к другому процессу. Параллельность процессов может быть несколько эмулирована с процессами TSR (Terminate and Stay Resident), которые остаются в памяти, несмотря на то, что их завершают, и можно возобновить их выполнение, перехватывая некоторые прерывания из их кода и вызывая его из другого кода позже. Тем не менее, это не тот тип параллелизма, который используется современными ОС, такими как Windows и Linux. Но дело не в этом.

Вы сказали, что используете NASM в качестве предпочтительного ассемблера, поэтому я предположил, что вы выводите свой код в COM-файлы, которые, в свою очередь, выполняются в командной строке DOS. COM-файлы загружаются из командной строки по смещению100h (после загрузки выполняется переход в это место) и не содержит ничего, кроме «худого» кода и данных - без заголовков, поэтому их проще всего создавать.

Я собираюсь объяснить источник сборки по частям, чтобы вы могли (возможно) получить лучшее представление о том, что происходит под капотом.

Программа начинается с

org 100h

section .data
exename db "C:\hello.com",0
exename2 db "C:\nasm\nasm.exe",0
cmdline db 0,0dh

theorgиректива @, которая указывает происхождение файла при фактической загрузке в память - в нашем случае это100h. Объявления трех меток следуют,exename а такжеexename2 которые являются путями с нулем в конце программ, которые нужно выполнить, иcmdline, который указывает командную строку, которую должен получить вновь созданный процесс. Обратите внимание, что это не просто обычная строка: первый байт - это количество символов в командной строке, затем сама командная строка и возврат каретки. В этом случае у нас нет параметров командной строки, поэтому все сводится кdb 0,0dh. Предположим, мы хотели передать-h -x 3 в качестве параметров: в этом случае нам нужно объявить этот ярлык какdb 8," -h -x 3",0dh (обратите внимание на дополнительное место в начале!). Двигаемся дальше ...

dummy times 20 db 0

paramblock dw 0
dw cmdline
dw 0 ; cmdline_seg
dw dummy ; fcb1
dw 0 ; fcb1_seg
dw dummy ; fcb2
dw 0 ; fcb2_seg

Ярлыкdummy - это всего лишь 20 байтов, которые содержат нули. Что следует заparamblock label, представляющий структуру EXEC, упомянутую Дэниелом Ретлисбергером. Первый элемент - ноль, что означает, что новый процесс должен иметь ту же среду, что и его родитель. Далее следуют три адреса: до командной строки, до первого FCB и второго FCB. Следует помнить, что адреса в реальном режиме состоят из двух частей: адреса сегмента и смещения в сегменте. Оба эти адреса имеют длину 16 бит. Они записаны в памяти с прямым порядком байтов, смещение будет первым. Поэтому мы указываем командную строку как смещениеcmdline и адреса FCB как смещения к меткеdummy, поскольку сами FCB не будут использоваться, но адреса в любом случае должны указывать на правильную ячейку памяти. Сегменты должны быть заполнены во время выполнения, так как загрузчик выбирает сегмент, в который загружается COM-файл.

section .text
entry:
    mov     ax,             cs
    mov     [paramblock+4], ax
    mov     [paramblock+8], ax
    mov     [paramblock+12],ax

Мы начинаем программу с установки полей сегмента вparamblock состав. Поскольку для COM-файлов,CS = DS = ES = SS, то есть все сегменты одинаковы, мы просто устанавливаем эти значения на то, что вcs регистр

mov     ax, 4a00h
mov     bx, 50
int     21h

Это одна из самых хитрых точек приложения. Когда COM-файл загружается в память DOS, ему по умолчанию назначается вся доступная память (CPU не имеет об этом никакого представления, поскольку он находится в реальном режиме, но внутренняя часть DOS все равно отслеживает его). Следовательно, вызов системного вызова EXEC приводит к сбою сNo memory available. Поэтому нам нужно сообщить DOS, что нам не нужна вся эта память, выполнив «БЛОК ИЗМЕНЕНИЯ ПАМЯТИ» AH=4Ah вызов (Ральф Браун).bx регистр должен иметь новый размер блока памяти в 16-байтовых единицах («параграфы»), поэтому мы установили его на 50, имея 800 байт для нашей программы. Я должен признать, что это значение было выбрано случайным образом, я пытался установить его на что-то, что имело бы смысл (например, значение, основанное на фактическом размере файла), но я продолжал получать в никуда.ES - это сегмент, который мы хотим «изменить», в нашем случае этоCS (или любой другой, так как они все одинаковы при загрузке COM-файла). После завершения этого вызова мы готовы загрузить нашу новую программу в память и выполнить ее.

    mov     ax, 0100h
    int     21h
    cmp     al, '1'
    je      .prog1
    cmp     al, '2'
    je      .prog2
    jmp     .end

.prog1:
    mov     dx, exename
    jmp     .exec

.prog2:
    mov     dx, exename2

Этот код должен быть достаточно понятен, он выбирает путь к программе, вставленной вDX на основе стандартного ввода.

.exec:
    mov     bx, paramblock
    mov     ax, 4b00h
    int     21h

Вот где фактическийEXEC syscall AH=4Bh) называется.AL содержит 0, что означает, что программа должна быть загружена и выполнена.DS:DX содержит адрес пути к исполняемому файлу (выбранному ранее фрагментом кода) иES:BX содержит адресparamblock метка, которая содержитEXEC состав

.end:
    mov     ax,     4c00h
    int     21h

После завершения выполнения программы вызываетсяexec, родительская программа завершается с нулевым кодом выхода при выполненииAH=4Ch системный вызов.

Благодаряvulture- из ## asm на Freenode за помощью. Я проверил это с DOSBox и MS-DOS 6.22, так что, надеюсь, это сработает и у вас.

Как ты думаешь, я могу одновременно запустить 2 программы? Jean Carlos Suárez Marranzini
Вы Не может есть приложения, работающиебуквальн в то же время. DOS не позволяет этого. Daniel Kamil Kozar
@ DanielKamilKozar: Хороший ответ. Это так полностью 1980-х годов ... Daniel Roethlisberger

Похожие вопросы