Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
Ixmil
2 / 25 / 0
Регистрация: 17.06.2013
Сообщений: 768
#1

Подскажите область фактической памяти для работы *com - программы

13.08.2018, 21:36. Просмотров 1656. Ответов 11
Метки нет (Все метки)

Подскажите начало диапазона фактических адресов памяти для работы собственно-ручно писанной *com - программы.
Моя программа предпологала бы работу с фактическими адресами памяти указанных константами. Но какой именно адрес, как начало рабочего диапазона следует использовать для обычно-пользовательской программы:
К примеру обращение к ячейке памяти:
Mov [1234], 4eh
Но какая именно по адресу ячейка памяти должна быть для обычной *com - программы чтобы это был номер начального адреса всей памяти преднозначенной для обычной программы?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.08.2018, 21:36
Ответы с готовыми решениями:

Написать программу, определяющую количество байтов памяти с ненулевыми значениями для первых 256 Кб физической памяти в реальном режиме работы Intel 8
Доброе время суток, моя задача похоже на задачу из этой темы...

На какую область памяти указывает адрес недоступной памяти
Здравствуйте! Написал программу, выводит (из PSP) сегментный адрес первого...

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

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

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

11
Kukuxumushu
970 / 528 / 96
Регистрация: 13.06.2015
Сообщений: 1,774
Завершенные тесты: 2
14.08.2018, 04:17 #2
Лучший ответ Сообщение было отмечено Mikl___ как решение

Решение

Ixmil, увы, программы грузятся DOS по произвольному адресу, и использование абсолютной адресации в них бессмысленно, кроме случаев обращения к строго регламентированным областям памяти DOS (к коим ваш случай, как я понимаю, не имеет никакого отношения).
3
Ethereal
Заблокирован
14.08.2018, 06:43 #3
Лучший ответ Сообщение было отмечено Jin X как решение

Решение

Цитата Сообщение от Ixmil Посмотреть сообщение
Подскажите начало диапазона фактических адресов памяти для работы собственно-ручно писанной *com - программы.
Адрес в 16-разрядном режиме IBM PC состоит из двух половин - сегмента и смещения. Вот так :
Абсолютный_адрес = 16*Сегмент + Смещение
Абсолютный адрес 20-разрядный. Сегмент и смещение 16-и разрядные.
При запуске COM-программы ее код помещается с заранее неизвестного сегмента. Зависит от того сколько было занято памяти при загрузке MS-DOS всякой лабудой, указанной в файлах CONFIG.SYS и AUTOEXEC.BAT. А вот смещение точки старта COM-программы всегда 100h.
Цитата Сообщение от Ixmil Посмотреть сообщение
К примеру обращение к ячейке памяти:
Mov [1234], 4eh
Здесь 1234 это смещение. А сегмент используется тот, что находится в регистре DS и при старте COM-программы этот регистр получит значение сегмента с которого программа загружена.
Так-что [1234] это смещение от заранее неизвестного сегмента. Но ты и не думай об этом сегменте. Когда загрузилась COM-программа все смещения в этом сегменте твои. Можешь делать с ними что хочешь. В общем, COM-программа грузится с заранее неизвестного сегмента, но все смещения в этом сегменте отдаются ей. Что в этих смещениях. В диапазоне смещений 0..100h префикс сегмента программы. Не трогай их без надобности. Со смещения 100h и дальше лежит код твоей программы с данными. Твори тут что-хошь. Но в самом хвосте, в смещениях ...FFFF находится стек. Ему надо хотя бы 200h байт места. Так-что диапазон смещений FE00..FFFF не трогай. А в диапазоне смещений 100..FDFF работай без ограничений. Там в перемешку твой код и данные. Данными код не затри, а в остальном твори что в голову взбредет.
5
Ixmil
2 / 25 / 0
Регистрация: 17.06.2013
Сообщений: 768
15.08.2018, 19:47  [ТС] #4
Большое спосибо.
0
Jin X
Заблокирован
17.08.2018, 12:33 #5
Ixmil, добавлю, что обычно делается так (TASM/MASM):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.MODEL Tiny
.286  ; разрешить использование инструкция процессора 80286
LOCALS  ; метки, начинающиеся на @@, считать локальными в пределах процедуры
JUMPS  ; заменять условные переходы на длинные расстояния двойными jump'ами (например, je X на jne Y + jmp X + Y:)
 
.CODE  ; начало кода
.STARTUP  ; точка входа (должна быть сразу после .CODE)
 
                ; тут идёт основной код
        
                int 20h  ; выход из программы
 
String          DB      'Здесь какая-то моя строка, которую я буду использовать в коде'
Values          DW      1000,30,40000,-1
ValueCount      =       ($-Values)/2  ; кол-во значений в Values
SomeData1       DW      100 DUP (0)  ; здесь 100 слов (по 2 байта) данных, заполненных нулями
SomeData2       DB      200 DUP (?)  ; здесь 200 байт каких-то неинициализированных данных
  ; (изначально там может быть что угодно, но эти данные не занимают места на диске программы,
  ; если после этой строки нет проинициализированных данных типа String, Values или SomeData1)
 
END
Либо так:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.MODEL Tiny
.286  ; разрешить использование инструкция процессора 80286
LOCALS  ; метки, начинающиеся на @@, считать локальными в пределах процедуры
JUMPS  ; заменять условные переходы на длинные расстояния двойными jump'ами (например, je X на jne Y + jmp X + Y:)
 
.DATA  ; начало проинициализированных данных
String          DB      'Здесь какая-то моя строка, которую я буду использовать в коде'
Values          DW      1000,30,40000,-1
ValueCount      =       ($-Values)/2  ; кол-во значений в Values
SomeData1       DW      100 DUP (0)  ; здесь 100 слов (по 2 байта) данных, заполненных нулями
 
.DATA?  ; начало НЕинициализированных данных
SomeData2       DB      200 DUP (?)  ; здесь 200 байт каких-то неинициализированных данных
  ; (изначально там может быть что угодно, но эти данные не занимают места на диске программы)
 
.CODE  ; начало кода
.STARTUP  ; точка входа (должна быть сразу после .CODE)
 
                ; тут идёт основной код
        
                int 20h  ; выход из программы
 
END
(это часто более удобно, причём блоки .CODE, .DATA и .DATA? можно располагать в любом порядке; и в отличие от программы типа .EXE, инициализация сегментных регистров DS, ES тут не нужна).

Добавлено через 4 минуты
Главное – не перемешивать код и данные (это можно делать только в том случае, если понимаешь зачем это делается и как делать это правильно). Т.е. не городить чего-то вроде:
Assembler
1
2
3
4
5
6
7
8
;...
  mov ah,9
  lea dx,String
  int 21h  ; вывод сообщения
String DB 'Hello World!',13,10,'$'
 
  int 20h
;...
Но вот так можно:
Assembler
1
2
3
4
5
6
7
8
9
10
;...
  mov ah,9
  call Output
String DB 'Hello World!',13,10,'$'
Output:
  pop dx
  int 21h  ; вывод сообщения
 
  int 20h
;...
(потому что это сделано знаючи как это работает, так как тут на String код не перейдёт; но просто так, не понимая механизма, так это делать не стоит)
3
Ixmil
2 / 25 / 0
Регистрация: 17.06.2013
Сообщений: 768
21.08.2018, 01:21  [ТС] #6
Извиняюсь. Но мне это незнакомо. Я собирался писать языком как из под дебагера.
Команда mov [1234], 3fh; И работала как последовательное обращение к адресам памяти как для нулевой ее страницы.
Т.е. позволяла записать в определённый адрес, и именно с определённого адреса считать что было и записанно.
Вроде можно было писать: mov[AX+BX], feh; но меня это волновало мало. Для меня подходила версия нулевой страницы памяти где полный фактический адрес в области показателей старше-числовой его половины был задан по умолчанию без уточнений которых могло и не быть.
0
Ethereal
Заблокирован
21.08.2018, 04:41 #7
Цитата Сообщение от Ixmil Посмотреть сообщение
где полный фактический адрес в области показателей старше-числовой его половины был задан по умолчанию без уточнений которых могло и не быть
Моя твой русский не понимай.
Цитата Сообщение от Ixmil Посмотреть сообщение
Т.е. позволяла записать в определённый адрес, и именно с определённого адреса считать что было и записанно.
MASM/TASM :
Assembler
1
2
mov byte ptr ds:1234h, 3Fh ; ну записал
mov al, ds:1234h ; ну считал
0
Ixmil
2 / 25 / 0
Регистрация: 17.06.2013
Сообщений: 768
21.08.2018, 10:48  [ТС] #8
Из соображения: mov [AX+BX],44h - как верного, я бы указывал только: mov [BX],44h; в качестве функции для записи в адрес указанный регистром "BX". Тогда когда полный адрес длиннее одного регистра, это означает что значение старшего разряда числового номера ячейки памяти задано по умолчанию в регистре (к примеру) "AX". А по умолчанию т.е. без специального присвоения значения регистр (в данном случае) "AX" имеет значение: "0000". Которое все равно определено как значение.

Добавлено через 2 минуты
Для обращения к нулевой странице памяти (диапазону), адрес можно указать не целиком. И старшие числовые разряды адреса примут значение: "0000".

Добавлено через 1 минуту
На правах обгрейтовости блоков памяти. (Когда они могут быть добавлены или нет).
0
Jin X
Заблокирован
21.08.2018, 11:46 #9
Цитата Сообщение от Ixmil Посмотреть сообщение
mov [AX+BX],44h - как верного, я бы указывал только: mov [BX],44h
Нет адресации по AX, если не использовать 32-битные регистры (тогда EAX можно и остальные тоже).
Из 16-битных регистров для адресации можно использовать только BX, BP (база, причём BP по умолчанию использует сегмент SS) и SI, DI (индекс). При этом складывать можно только 1 базовый и 1 индексный ([BX+SI], [BX+DI], [BP+SI], [BP+DI]; а вот [BX+BP] или [SI+DI] нельзя). Либо адресовать по 1 из этих 4-х регистров. Так же можно в любом из случаев добавлять/вычитать смещение (числовое значение): [BP+1234h] (тут по умолчанию будет сегмент SS), [BX+SI-80h].
Если сумма получается больше 0FFFFh, старшие неуместившиеся разряды игнорируются, т.е. вместо 12345h используется 2345h. Никаких значений по умолчанию в регистрах нет. Регистры содержат то, что в них записали. Если при старте программы ничего в них не записывалось, это не значит, что там ноль, и перед тем, как их использовать, нужно в них что-то записать (обнулить, если надо).

Добавлено через 2 минуты
Когда пишешь в память значение (или сравниваешь память со значением), нужно указывать размерность, т.к. ассемблеру не понятно, что значит число 1 – это байт, слово или двойное слово. Пишем mov byte ptr [bx+si],1 или типа того.

Добавлено через 3 минуты
При адресации с BP есть ещё одна особенность (кроме использования SS по умолчанию): в опкод обязательно прописывается смещение. Если оно не указано, прописывается 0 (т.е. mov [bp],ax фактически генерирует mov [bp+0],ax, а mov [bp+si],ax = mov [bp+si+0],ax, т.е. длина такой инструкции на 1 байт больше, чем, скажем, у mov [bx],ax или mov [bx+si],ax). Размер опкода с использованием [BX] и [BX+SI], [BX+DI] одинаков. Аналогично при использовании [BP] и [BP+SI], [BP+DI] генерируются коды одного размера.
4
Ixmil
2 / 25 / 0
Регистрация: 17.06.2013
Сообщений: 768
21.08.2018, 12:26  [ТС] #10
Спосибо. Но я не вижу для себя смысла больше продолжать эту тему.
0
politoto
111 / 105 / 4
Регистрация: 23.07.2018
Сообщений: 201
21.08.2018, 15:02 #11
Цитата Сообщение от Ethereal Посмотреть сообщение
COM-программа все смещения в этом сегменте твои. Можешь делать с ними что хочешь. В общем, COM-программа грузится с заранее неизвестного сегмента, но все смещения в этом сегменте отдаются ей. Что в этих смещениях. В диапазоне смещений 0..100h префикс сегмента программы. Не трогай их без надобности. Со смещения 100h и дальше лежит код твоей программы с данными
Если хочется однобайтовых смещений, можно использовать часть PSP с 80 по FF.
Код
0x80 	1 	Length of command line.
0x81 	127 	Command line contents.
Ничего ценного для себя DOS там хранить не могла, т.к. по умолчанию там располагается буфер обмена с дискетой в стиле CP/M.
0
Jin X
Заблокирован
27.08.2018, 22:11 #12
Цитата Сообщение от Jin X Посмотреть сообщение
а mov [bp+si],ax = mov [bp+si+0],ax
Обманул я вас, други! Извиняюсь...
Смещение добавляется только для одинокого BP, т.е. для mov ax,[bp] будет сгенерировано mov ax,[bp+0], а вот для mov ax,[bp+si] или mov ax,[bp+di] – нет
0
27.08.2018, 22:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.08.2018, 22:11

Утечка памяти программы работы с COM портом
Здравствуйте, недавно перешёл на C# попробовал простенький пример считывать...

Подсчет времени работы программы и затрат памяти
Есть программа, которая переупорядочивает УПОРЯДОЧЕНЫЙ предварительно массив...

Подскажите прицип работы программы
Добрый день! Сразу прошу прощения за офф-топ, к сожалению не знаю в какую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru