Вот начал разбираться с ассемблером, поэтому сильно не пинать, я еще новичок 8) Пишу программу (DOS), которая загружает во внутрь себя другую программу, которая должна выполнится. Все вроде бы просто, но все смещения в загруженной программе становятся неправильными, соответсвенно она и работает неправильно.. Я пытался скорректировать регистр ds. Но что-то не получилось. Программа продолжает выдавать какой-то мусор. Вот код: CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h ;начало start: jmp run Handle dw 0 Mess_ok db 'File loadet into memory!$' Mess_error db 'File error ' File_name db 'hello.com',0,'!$' run: mov ax,3D00h ;Открываем файл mov dx,offset File_name int 21h jc Error_file mov Handle,ax mov bx,ax mov ah,3Fh ; Считываем файл mov cx,23 ; Его длина 23 байта mov dx,offset pstart int 21h jc Error_file mov ah,3Eh ;Закрываем файл mov bx,Handle int 21h jc Error_file mov dx,offset Mess_ok mov ah,9 int 21h mov ax,ds ;Это я ытался скореектировать ds. add ax,offset pstart ;Было еще 2 варианта mov ds,ax ;коррекции, но ничего не ;вышло.. pstart: ;Сюда загружена программа error_file: mov dx,offset Mess_error mov ah,9 int 21h int 20h CSEG ends end start Вот программа которую я пытаюсь загрузить: CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h start: mov ah,9 mov dx,offset message int 21h ret message db "Hello world!",0Dh,0Ah,'$' CSEG ends end start
oxid ИМХО написан полный бред... Объясни задачу. Если надо запустить другой exe то для этого есть специальная функция. Иначи то что ты делаешь аналогично просто перезоду в определенное место
Нет, дело вне в том, чтобы запустить определенный exe. А в том чтобы скопировать в буффер любую com программу и выполнить ее. У меня копируется не в буффер, а прямо в середину программы. Или как частный случай можно сказать, что я часть кода своей программы хочу заменить на код из другой com программы. Кстати попробуйте вместо второй программы сохранитьот эту: hello.com CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h start: call r a equ message-r r: pop bx ;ax=ip add bx,a ; bx==offset message mov ah,9 mov dx,bx int 21h ret message db "Hello world!",0Dh,0Ah,'$' CSEG ends end start Здесь смещение вычисляется во время выполнения программы. Просто может я плохо объясняю..
oxid уже немного понятно. Для того чтобы прочитать и запустить COM файл я бы делал так: 1. Изменил размер памяти которуй занимает хост 2. Создал PSP 3. Считал по адресу PSP:100h com программу 4. Выставил регистры нужным образом. 5. Прыжок на PSP:100 После этого все должно быть нормально, хотя я и не пробывал
А гед можно почитать про PSP? И кстати, может быть проще считать программу по адресу кратному 16, и установить сегментные регистры на (это место-100h)/16 ? Ведь проблема только с содержимым ds.. Если прога не содерржит статических смещений, то все пашет.
Вот здесь отлично расписано как работает функция EXEC: http://kalashnikoff.ru/Assembler/issues/029.htm
Сохраняй все регистры,копируй функцию загрузки в 65535-"размер кода загруки" и грузи любой ком (ну не любой, тот который не затрёт код загрузчика, ну или пихай загрузчик в стёк или выделяй память) с 100h в текущий CS, дальше востанавливай регстры и jmp 100h P.S. Хотя это бред.... правда у тебя написан не меньший =) P.P.S. Стёк помоему в том же сегменте, что и данные с кодом для кома, что то подзабыл уже... соответсвенно максимальный размер = FFFFh-100h-"Размер кода загрузчика"-"размер стёка"+1
Фсё правильно, только нужно сделать так, чтобы comу было доступно 64к. Стек растёт с конца сегмента. Тогда всё заработает. Да, и PSP нужно оформить должным образом. Система его активно пользует.
Раскопали тему трехлетней давности... Все просто: нужно либо использовать функцию EXEC, предварительно побеспокоившись о том, чтобы память выше данной программы была доступна, либо встроить код загружаемой программы выше текущего PSP, предварительно переместив "управляющий код" на свободное место и при необходимости подправив имя исполняемого файла, находящееся после блока переменных среды, с чем кстати могут возникнуть проблемы в том случае, когда новое имя длиннее старого.