Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Загрузка данных из другого сегмента

12K
12 февраля 2010 года
ASoftware
87 / / 16.04.2009
Если честно, мне надоело безполезно скитаться третий день по интернету, вот решил спросить здесь, ибо нет сил.
Простое чтение файла:
Код:
; получаем описатель
        mov ax,3d00h   ; ah - 3dh; al - 00 (for reading)
        mov dx,file_name

        int 21h
        jc err_exit
        mov [handle16],ax
 
; читаем через описатель
        mov ah,3fh
        mov bx,[handle16]

        mov dx,adress  

        mov cx,87        ; 87 байт
        int 21h

        cmp ax,cx
        jne err_exit
       
; вывод содержимого файла
       mov ah,9h
       mov dx,adress
       int 21h

int 20h

err_exit:
int 20h

handle16 dw 0x00
filename db 'myfile.dat',0
adress:


Все прекрасно работает, но только в этом сегменте. Я хочу загрузить файл размером 64 Кб в другой сегмент (т.е. не тот где сейчас код) и так как в функции 3fh запись файла происходит в буфер по адресу DS: DX, то по идеи чтобы загрузить в этот семент файл то стоит написать так:

; читаем через описатель
push ds ; сохраним сегмент данных
mov ax,0xD000 ; в этот сегмент загрузим файл
mov ds,ax

mov ah,3fh
mov bx,[handle16]
mov dx,0 ; со смещением 0
; т.е. по сути данные из файла будут располагаться по адресу D000h:0000h, или я не прав?

mov cx,87 ; 87 байт
int 21h
pop ds ; возвратим ds на кодовый сегмент
cmp ax,cx
jne err_exit

А теперь я хочу вывести текст, который находится по адресу D000h:0000h на экран. Т.е. это будет выглядеть так:


mov ax,0xD000
mov ds,ax

mov ah,9h
mov dx,0
int 21h

Если не менять ds вообще в программе - то все работает нормально, файл загружается, после чего той же функцией 9й выводится на экран.
Т.е. когда файл и код в одном сегменте - то все нормально.

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

И вообще, зачем регистру ds знать где находятся данные, ведь программист всегда сделает так:
......
code
......
jmp next_code
data1 db 'asdasd',0
data2....
data3....
next_code:
.....
code
......

Или это нужно для того чтобы загружать в кеш только код, а не все подряд?

И как в фасме будет выглядеть конструкция типа
.DATA
........
.CODE
mov ax,@data
mov ds,ax

Вариант в фасме типа
dataSEG:
.....bla bla...
codeSEG:

mov ax,dataSEG
mov ds,ax

Не катит - пробовал
252
12 февраля 2010 года
koderAlex
1.4K / / 07.09.2005
почему сегмент 0xd000 ?
код комовской проги :
 
Код:
; fasm example of writing 16-bit COM program
    org 100h            ; code starts at offset 100h
    use16               ; use 16-bit code
display_text = 9
    mov ah,display_text
    mov dx,hello
    int 21h
    int 20h
hello db 'Hello world!',24h

код экзешной проги :
 
Код:
; fasm example of writing simple EXE program
format MZ
    push    cs
    pop ds
    mov ah,9
    mov dx,hello
    int 21h
    mov ax,4C00h
    int 21h
hello db 'Hello world!',24h
12K
12 февраля 2010 года
ASoftware
87 / / 16.04.2009
почему сегмент 0xd000 ?
Потому что данные из файла я хочу загрузить в другой сегмент (не в тот где сейчас находится программа) а в другой, так как файл будет занимать ровно 64Кб (в размер сегмента). Вот я и хочу поместить его в свободный сегмент. По таблице с физического адреса 0xD0000 начинаются свободные адреса.

Возможно файл будет занимать и больше чем 64Кб, тогда его прийдется загружать в несколько сегментов по частям. Вопрос: как записать данные в 1,2,3,10 и т.д. сегменты?
399
12 февраля 2010 года
KIV
432 / / 20.01.2009
Сегмент 0xD000 (физический адрес 0xD0000) не сегмент физической памяти.
Физическая память идёт до адреса 0x9FFFF и после 0x100000 (не доступно из обычного реального режима). А память 0xA0000 - 0xFFFFF - видео буфер, BIOS, и просто отсутствующие участки памяти. Причём всё кроме видео буфера (0xA0000 - 0xBFFFF, кажется, с верхней границенй могу ошибаться) доступно только как ReadOnly и чтение туда файла ни к чему не приводит. А вообще нежелательно самому выделять память в DOS. Ведь эта память может быть уже выделенна под другое и её изменение приведёт к нестабильной работе системы. Лучше для этого использовать функции DOS для выделения/освобождения блоков памяти.
399
12 февраля 2010 года
KIV
432 / / 20.01.2009
"Свободные адреса" - адреса которым не соответствует никакая память ни BIOS, ни видео-буфер. Запись в эти участки ничего не изменит. Чтение вернёт 0xFF.
12K
12 февраля 2010 года
ASoftware
87 / / 16.04.2009
Ну хорошо.. Допустим в ДОСе еще можно найти с помощью функции свободный сегмент...
А как быть в БИОСе ?
Неужели загруженные файлы хранить, не дай Бог, в видеопамяти? Ведь все остальное ReadOnly..
399
12 февраля 2010 года
KIV
432 / / 20.01.2009
Ну нет конечно же, не в видео-памяти.
Что значит в BIOS? Это когда нет ОС? Тогда варианта два: либо писать свой менеджер памяти, либо использовать фиксированный адрес (я говорил что этот вариант не приемлем в DOS, но без оськи он вполне подходит, только делайте адрес выше 0x400 и ниже 0x9FFFF). Но учтите, что в BIOS нет не только функций работы с памятью, но и функций работы с файлами (только с секторами диска), поэтому драйвер файловой системы придётся писать самому.
12K
13 февраля 2010 года
ASoftware
87 / / 16.04.2009
Ну вот... уже час ночи, а я все еще не успокоюсь..ну не могу я когда я что то не могу сделать/не понимаю.

Повторюсь - задачей является загрузка файла (средствами функций ДОС 3dh и 3fh) в память в свободный сегмент памяти, и вывод всего текста из файла на экран (именно из свободного, отдельного от кода, сегмента).

Ну вот проблемы следующие:
1) Функция 48h - распределить память. Т.е. я задаю размер памяти требуемый, функция возвращает сегментный адрес свободного блока...
Но стоит только затребовать больше 7 параграфов, то сразу carry устанавливается в 1 и ошибка... А 7 параграфов по 16 байт это 112 байт. Это что размер свободной памяти?

2) Даже с этими 7ю параграфами программа не хочет работать. Как будто бы издевается надо мной. То выводит какую то фигню на экран, то пишет error потому что cx считанных байт не совпадают с запрошенным ax байтами, то еще что то.. Уже честно, нет сил... Опять сегодня ложусь в пол второго ночи...Блин!))) А из за такой фигни))

Если кому не лень, посоветуйте что нибудь, подправьте или ткните носом куда надо, либо кодом, что нибудь. Заранее спасибо..

Код только кажется большим, на самом деле он простой, и понятный.
вот:
Код:
org 100h

   mov   ah,48h      ;нoмep функции
   mov   bx,7           ;тpeбуeм 7 пapaгpaфов, если больше 7 - то ошибка :(((((
   int   21h                    ;пытaeмcя oтвecти блoк
   jc    ERROR          ;oбpaбaтывaeм oшибку в cлучae нeудaчи
   mov [BLOCK_SEG],AX;инaчe coxpaняeм aдpec блoкa

;---ocвoбoждaeм тoт жe блoк
   MOV AX,[BLOCK_SEG] ;пoлучaeм cтapтoвый aдpec блoкa
   MOV ES,AX             ;пoмeщaeм eгo в ES
   MOV AH,49H             ;нoмep тpeбуeмoй функции
   INT   21H                     ;ocвoбoждaeм блoк пaмяти







   ; ------ OPEN FILE --------
   mov ax,3d00h   ; ah - 3dh; al - 00 (for reading)
   mov dx,filename

   int 21h
   jc ERROR
   mov [handle16],ax

   ; ----- GET DATA FROM HANDLE

   mov ax,[BLOCK_SEG]
   mov ds,ax            ; занесем данные в освобожденный сегмент
   mov ah,3fh
   mov bx,[handle16]
   xor dx,dx           ; DS:0000
   mov cx,87           ; 87 bytes (мой файл размером в 87байт)
   int 21h

   cmp ax,cx           ; обработаем ошибку
   jne ERROR



   ; ----- CLOSE FILE -----
    mov ah,3eh
    mov bx,[handle16]
    int 21h


   ; ------ WRITING MESSAGE -----
   ; выведем загруженный текстовый файл на экран (файл в сегменте DS:0000)
   push [BLOCK_SEG]
   pop ds        ; указателем на адрес строки служит DS:DX
   mov dx,0
   mov ah,9h
   int 21h







; WAIT AND EXIT            ; Ожидание и выход
xor ah,ah
int 16h
int 20h

    filename db 'maph.dat',0
    c_err db 'error$'

BLOCK_SEG dw 0x00
handle16 dw 0x00


; Выведем сообщение, если произошла ошибка
ERROR:
push cs
pop ds
mov ah,9h
mov dx,c_err
int 21h
xor ah,ah
int 16h
int 20h


P.S. И что значит "Вы должны добавить отзыв кому то еще, прежде чем добавить его KIV?"
KIV, почему я тебе не могу "+" поставить?
399
13 февраля 2010 года
KIV
432 / / 20.01.2009
Цитата:
P.S. И что значит "Вы должны добавить отзыв кому то еще, прежде чем добавить его KIV?"
KIV, почему я тебе не могу "+" поставить?


Это защита от накруток. Знапчит вы мне недавно отзыв отправили. Нодо поблогодарить кого то ещё (не просто так размеется)...
P.S. Сейчас посмортрю код и попробую помочь.

399
13 февраля 2010 года
KIV
432 / / 20.01.2009
У меня тоже больше семи параграфов не выделяет. Чтото странное.
Освобождать память нужно после использования, а не перед.
Код:
org 100h

   mov     ah,48h      ;нoмep функции
   mov     bx,7            ;тpeбуeм 7 пapaгpaфов, если больше 7 - то ошибка :(((((
   int     21h                    ;пытaeмcя oтвecти блoк
   jc     ERROR            ;oбpaбaтывaeм oшибку в cлучae нeудaчи
   mov [BLOCK_SEG],AX;инaчe coxpaняeм aдpec блoкa

  ; ------ OPEN FILE --------
   mov ax,3d00h   ; ah - 3dh; al - 00 (for reading)
   mov dx,filename

   int 21h
   jc ERROR
   mov [handle16],ax

   ; ----- GET DATA FROM HANDLE

   mov ax,[BLOCK_SEG]
   mov ds,ax            ; занесем данные в освобожденный сегмент
   mov ah,3fh
   mov bx,[handle16]
   xor dx,dx           ; DS:0000
   mov cx,87           ; 87 bytes (мой файл размером в 87байт)
   int 21h

   cmp ax,cx           ; обработаем ошибку
   jne ERROR



   ; ----- CLOSE FILE -----
    mov ah,3eh
    mov bx,[handle16]
    int 21h


   ; ------ WRITING MESSAGE -----
   ; выведем загруженный текстовый файл на экран (файл в сегменте DS:0000)
   push [BLOCK_SEG]
   pop ds         ; указателем на адрес строки служит DS:DX
   mov dx,0
   mov ah,9h
   int 21h
;---ocвoбoждaeм тoт жe блoк
   MOV AX,[BLOCK_SEG] ;пoлучaeм cтapтoвый aдpec блoкa
   MOV ES,AX             ;пoмeщaeм eгo в ES
   MOV AH,49H             ;нoмep тpeбуeмoй функции
   INT     21H                     ;ocвoбoждaeм блoк пaмяти






; WAIT AND EXIT            ; Ожидание и выход
xor ah,ah
int 16h
int 20h

    filename db 'maph.dat',0
    c_err db 'error$'

BLOCK_SEG dw 0x00
handle16 dw 0x00


; Выведем сообщение, если произошла ошибка
ERROR:
push cs
pop ds
mov ah,9h
mov dx,c_err
int 21h
xor ah,ah
int 16h
int 20h
12K
13 февраля 2010 года
ASoftware
87 / / 16.04.2009
Цитата:
Освобождать память нужно после использования, а не перед.


Как после? я так понимаю необходимо очистить сегмент полностью чтобы в него записать какие то данные... значит надо перед..

Хех) А программа все равно не работает... по видимому сегмент освобождается, и 48 функция делает свое дело.. но вот что касается загрузки файла туда...
; ----- GET DATA FROM HANDLE

mov ax,[BLOCK_SEG]
mov ds,ax ; занесем данные в освобожденный сегмент
Проблема в этом... Если в ds загрузить кодовый сегмент - то все нормально, файл загружается в кодовый сегмент.. но мне то нужно в полностью свободный.. И когда загружаешь в ds значение BLOCK_SEG то происходит ошибка...ax байт не совпадает с cх считанных...


P.S. Можно переформулировать мой вопрос:
Как загрузить файл (любым способом, но только в real mode) в оперативную память, который имеет размер 64Кб или более ?

12K
14 февраля 2010 года
ASoftware
87 / / 16.04.2009
И даже никто не сталкивался с такой проблемой? А если у меня процессор 8086, то мне файл никак не загрузить???
252
16 февраля 2010 года
koderAlex
1.4K / / 07.09.2005
в приложенном файле прога для нереального режима через регистры GS и FS и пример работы .
для работы нужно в config.sys убрать emm*.* , а для himem.sys поставить
опции "/A20CONTROL:OFF /TESTMEM:OFF" или , если возможно, тоже убрать .
также отключи из биоса ACPI .
запускаешь flat.com , вручную или через autoexec.bat , и можешь пользовать всю верхнюю память как угодно . для варианта с himem.sys начиная с 64 мегабайта , а для варианта без himem.sys начиная со 2-го .
12K
17 февраля 2010 года
ASoftware
87 / / 16.04.2009
О, это супер вариант!
Только вот неразобравшись с сегментами идти мне дальше будет как то неправильно...
Вот разберусь и пойду дальше..
А вариант супер! +1
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог