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

Ваш аккаунт

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

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

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

Почему смещение именно такое?

76K
12 июня 2013 года
brudor
27 / / 17.04.2013
Рассмотрим простейший код на tasm:

Код:
.model small
.data
msg db 'Hello $'
.code
start:
mov ah,09h
mov dx, offset msg
int 21h
mov ah, 4Ch
int 21h
end start
Компилю и линкую в exe, запускаю и вылетает непойми че вместо Hello. Открыл дебуггер, там msg находится по смещению 0108, непонятно почему, а в dx при этом пишется 0008. Помогите в этом разобраться. Конечно, если записать mov dx, offset msg+100h то все нормально, но мне не понятно почему так произошло? Еще не понятно, почему программа не завершается, если вмпесто вызвоа функции 4Ch написать ret или int 20h?
247
12 июня 2013 года
wanja
1.2K / / 03.02.2003
Пши
lea dx,msg
76K
12 июня 2013 года
brudor
27 / / 17.04.2013
Так разве жто не тоже самое что mov dx, offset msg? В любом случае вопрос не в том как это испрвить, это можно сделать просто записав mov dx, offset msg+100h, а почему линкер в dx пихает 0008 а msg ледит по смещению 0108?
326
12 июня 2013 года
sadovoya
757 / / 19.11.2005
Возможно assume ds не хватает, чтобы правильно работало. Надо посмотреть что дирекивы .model small и .data в tasm делают. Т.е., туда-ли указывает ds, чтобы верным было смещение ваших данных.

P.S. DS на данные можно настроить так еще:

 
Код:
mov ax,@data
mov ds,ax
А в паре регистров DS:DX должен содержаться весь адрес вашей строки. После этого вызов 09h прерывания DOS 21h ее напечатает.
247
13 июня 2013 года
wanja
1.2K / / 03.02.2003
И еще я сильно подозреваю, что куда-то оно пихает стек(по умолчанию)... Может, как раз туда.
326
16 июня 2013 года
sadovoya
757 / / 19.11.2005
Похоже не стек (сам вначале так заподозрил), а PSP. Как удалось вычитать, при загрузке автоматически DS настроен на PSP, а у нее как раз размер 100h. Поэтому без настройки DS на данные имеем эту сбивку адресов. Лучше проверить, распечатав, например, коммандную строку. Она хранится в PSP со смещения 81h. Вот код:

Код:
.model small
;этой программе стек и данные не нужны
.code  
Entry:  
        ;При загрузке exe-программы DS автоматически настроен на PSP
    mov dx, 81h ; в dx помещаем смещение коммандной строки в PSP (81h)
        ;Теперь в паре ds:dx адрес ком. строки и можно вывести ее на печать:
        mov ah, 09h        
        int 21h

        mov ah, 4ch
        int 21h
end Entry
Получаемый из этого исходника exe-файл запускаем с какой-нибудь коммандной строкой (завершите ее только символом $, лень было нормальную реализацию писать). На выходе ее и получим (без $ разумеется).
7
17 июня 2013 года
@pixo $oft
3.4K / / 20.09.2006
А Org 100h не поможет?
326
18 июня 2013 года
sadovoya
757 / / 19.11.2005
Возвращаясь к началу темы, по поводу выхода по int 20h -- для этого надо CS установленный на PSP. См. здесь. А у вас CS на код указывает.

Цитата:
А Org 100h не поможет?


Каким образом? Может, я что не догоняю?..

76K
19 июня 2013 года
brudor
27 / / 17.04.2013
Вопрос: Что будет происходить если определить модель tiny и собрать в .exe? Я рассуждал так: После ассемблирования мы получим объектный файл где проставлены смещения начала данных и кода, потом после сборки линкер тупо создаст relocation table куда проставит адреса начала кода и данных разбив тот сегмент (и стека, если указан), который описан в объектнике. Верно?
349
20 июня 2013 года
Phantom-84
656 / / 27.10.2005
Проще проверить. Хотя если рассуждать теоретически, то tiny предназначена для com-файлов и позволяет объединить в одном сегменте код, данные и стек, причем стек располагается под верхней границей полного 64-килобайтного сегмента.
326
20 июня 2013 года
sadovoya
757 / / 19.11.2005
Возможно вас заинтересует -- нашел у себя в запасах кода программу, которую можно и как com (.tiny) и как exe собрать. Для Masm. Для сборки в com надо ml comexe.asm /AT. Для exe - без ключа AT. Для exe ассемблер предупредит, что стека нет - это нормально.

Код:
;------------------------------------------------------------
TITLE COMEXE
;Вывод текста в текущее положение курсора. Программа будет
;работать, как в ЕХЕ-, так и СОМ-варианте
;------------------------------------------------------------

CODSEG SEGMENT
ASSUME CS:CODSEG, DS:CODSEG, SS:CODSEG, ES:CODSEG
ORG 100H
BEGIN:              
JMP BEG_CODE        
                   
TEXT DB 'This Programm in Assembler.',13,10,'$'
                    ;$ - признак конца строки
                    ;13,10 - перевод строки
BEG_CODE:           ;метка начала основного входа
;-----------------------------------------------------------
;две следующие строки необходимы для правильной работы
;ЕХЕ-программы, для СОМ-программы их можно опустить
MOV AX,CS           ;содержимое регистра CS
MOV DS,AX           ;пересылаем в регистр DS
;-----------------------------------------------------------
;--вывод строки--
LEA DX,TEXT        
MOV AH,9            
INT 21H
;--теперь выходим в операционную систему
MOV AH,4CH        
INT 21H            
CODSEG ENDS         ;конец сегмента
END BEGIN
76K
21 июня 2013 года
brudor
27 / / 17.04.2013
Цитата: Phantom-84
Проще проверить. Хотя если рассуждать теоретически, то tiny предназначена для com-файлов и позволяет объединить в одном сегменте код, данные и стек, причем стек располагается под верхней границей полного 64-килобайтного сегмента.


Я проверил. Физический адрес начала data и code отличается на 10h. Все как Вы и говорили, действительно линковка в exe и получаем, что ds указывает на сегмент с PSP. И все бы хорошо, но после пересылки в ds адрес сегмент данных лежит не по нулевому смещению, по нулевом лежит черти-че.

Код:
;Линковка .EXE

.model tiny
.stack 100h
.data
msg db 'Hello $'
.code
start:
mov ax,@data
mov ds, ax
mov dx, offset msg
mov ah, 09h
int 21h
mov ah, 4Ch
int 21h
end start
Попробую порассуждать: смещение строки msg относительно начала PSP- 0110. После пересылки в ds Начала сегмента данных смещение становится 0010. Такое ощущение, что линкер проставляет начало сегмента данных через 100h байт после начала PSP. Но там же есть relocation table в котором описаны адреса, разве нет?

sadovoya, интересный пример, спасибо! Одна непонятка: Я могу менять содержимое сегментных регистров в com-программе, но как только я написал
 
Код:
mov ax, @data
mov ds, ax
то линкер ругается segment-relocatable item present in HELLO.EXE. я не совсем понимаю, почему он не ругается на
 
Код:
mov ax, 0Fff7h
mov ds,ax
349
22 июня 2013 года
Phantom-84
656 / / 27.10.2005
Цитата: brudor
Я проверил. Физический адрес начала data и code отличается на 10h. Все как Вы и говорили, действительно линковка в exe и получаем, что ds указывает на сегмент с PSP. И все бы хорошо, но после пересылки в ds адрес сегмент данных лежит не по нулевому смещению, по нулевом лежит черти-че.

Это вполне естественно. Во-первых, в tiny код всегда идет на первом месте, а во-вторых, если ты использовал что-то типа org 100h, то в начало сегмента могут быть вставлены 100h байт данных.

Цитата:
Одна непонятка: Я могу менять содержимое сегментных регистров в com-программе, но как только я написал
 
Код:
mov ax, @data
mov ds, ax
то линкер ругается segment-relocatable item present in HELLO.EXE. я не совсем понимаю, почему он не ругается на
 
Код:
mov ax, 0Fff7h
mov ds,ax

Опять все вполне естественно. В tiny все объединяется в один сегмент, причем код, как я уже говорил, идет на первом месте, т.е. в лучшем случае ты сможешь обратиться в exe-шнике к @code. В com-файле подобных сегментных адресов не должно быть вообще, потому что никаких релоков там и в помине нет. Естественно, если использовать обычную константу в качестве сегментного адреса, все будет работать, т.к. ассемблер/компоновщик никак по-особому такие адреса не обрабатывает.

76K
23 июня 2013 года
brudor
27 / / 17.04.2013
Цитата: Phantom-84
Это вполне естественно. Во-первых, в tiny код всегда идет на первом месте, а во-вторых, если ты использовал что-то типа org 100h, то в начало сегмента могут быть вставлены 100h байт данных.


Понимаете в чем дело, я не вполне понимаю как работает ассемблер и линкер и хочу в этом разобраться. Вот код:

Код:
;Линоквка .EXE
.model tiny
.data
msg db 'Hello $'
.code
org 100h
start:
mov ax,@data
mov ds, ax
mov dx, offset msg
mov ah, 09h
int 21h
mov ah, 4Ch
int 21h
end start
Компилирую и смотрю .LST, вот что там написано:
Код:
Turbo Assembler  Version 4.1        06/23/13 16:49:51       Page 1
hello.ASM



      1 0000                 .model tiny
      2 0000                 .data
      3 0000  48 65 6C 6C 6F 20 24   msg db 'Hello $'
      4 0007                 .code
      5
      6 0000                 start:
      7 0000  B8 0000s           mov ax,@data
      8 0003  8E D8          mov ds, ax
      9 0005  BA 0000r           mov dx, offset msg
     10 0008  B4 09          mov ah, 09h
     11 000A  CD 21          int 21h
     12 000C  B4 4C          mov ah, 4Ch
     13 000E  CD 21          int 21h
     14                  end start
Turbo Assembler     Version 4.1        06/23/13 16:49:51       Page 2
Symbol Table




Symbol Name           Type   Value

??DATE                Text   "06/23/13"
??FILENAME            Text   "hello   "
??TIME                Text   "16:49:51"
??VERSION             Number 040A
@32BIT                Text   0
@CODE                 Text   DGROUP
@CODESIZE             Text   0
@CPU                  Text   0101H
@CURSEG               Text   _TEXT
@DATA                 Text   DGROUP
@DATASIZE             Text   0
@FILENAME             Text   HELLO
@INTERFACE            Text   000H
@MODEL                Text   1
@STACK                Text   DGROUP
@WORDSIZE             Text   2
MSG               Byte   DGROUP:0000
START                 Near   DGROUP:0000

Groups & Segments         Bit Size Align  Combine Class

DGROUP                Group
  _DATA               16  0007 Word   Public  DATA
  _TEXT               16  0010 Word   Public  CODE
Попробую распарсить:
Код:
1 0000                 .model tiny
      2 0000                 .data
      3 0000  48 65 6C 6C 6F 20 24   msg db 'Hello $'
      4 0007                 .code
      5
      6 0000                 start:
      7 0000  B8 0000s           mov ax,@data
      8 0003  8E D8          mov ds, ax
      9 0005  BA 0000r           mov dx, offset msg
     10 0008  B4 09          mov ah, 09h
     11 000A  CD 21          int 21h
     12 000C  B4 4C          mov ah, 4Ch
     13 000E  CD 21          int 21h
     14                  end start
Тут, как я понял, записаны номер строки, смещение относительно отнсоительно сегмента данных и кода, инструкция и ее ассемблерный эквивалент.
Код:
Symbol Name           Type   Value

??DATE                Text   "06/23/13"
??FILENAME            Text   "hello   "
??TIME                Text   "16:49:51"
??VERSION             Number 040A
@32BIT                Text   0
@CODE                 Text   DGROUP
@CODESIZE             Text   0
@CPU                  Text   0101H
@CURSEG               Text   _TEXT
@DATA                 Text   DGROUP
@DATASIZE             Text   0
@FILENAME             Text   HELLO
@INTERFACE            Text   000H
@MODEL                Text   1
@STACK                Text   DGROUP
@WORDSIZE             Text   2
MSG               Byte   DGROUP:0000
START                 Near   DGROUP:0000
Что тут написано не вполне понятно. Что означает например ??DATE ? @- это получение адреса, как понять
 
Код:
@MODEL                Text   1
?
 
Код:
Groups & Segments         Bit Size Align  Combine Class

DGROUP                Group
  _DATA               16  0007 Word   Public  DATA
  _TEXT               16  0010 Word   Public  CODE
Здесь, надо полагать, инфа о сегментах и их тип. _DATA- сегмент данных, _TEXT- сегмент кода. Что означают остальные параметры: Bit, Size, Align, Combine?
252
24 июня 2013 года
koderAlex
1.4K / / 07.09.2005
"Что означает например ??DATE" - текущая дата на момент компиляции .
"@- это получение адреса, как понять" - никак . это не получение адреса , а имя внутренней переменной компилятора .

"Я могу менять содержимое сегментных регистров в com-программе, но как только я написал
mov ax, @data
mov ds, ax
то линкер ругается segment-relocatable item present in HELLO.EXE" - ругается на .EXE в .COM-программе ? :) на @data в коме и должен ругаться , ибо его (сегмента данных) в коме нету и переменная компилятора @data не инициализирована .
когда вы пишете
mov ax, 0Fff7h
mov ds,ax
или
mov ax, cs
mov ds,ax
компилятор очень сильно надеется на ваши мозги :) , потому и не ругается .
349
24 июня 2013 года
Phantom-84
656 / / 27.10.2005
exe-шник тоже не мешало бы показать...
76K
24 июня 2013 года
brudor
27 / / 17.04.2013
Цитата: koderAlex
"Что означает например ??DATE" - текущая дата на момент компиляции .
"@- это получение адреса, как понять" - никак . это не получение адреса , а имя внутренней переменной компилятора .


Что такое внутренняя переменная компилятора?
Phantom, вы имели в виду .MAP? Вот он, если что:

 
Код:
Start  Stop   Length Name               Class

 00000H 0010FH 00110H _TEXT              CODE
 00110H 00116H 00007H _DATA              DATA

Program entry point at 0000:0100
Warning: No stack
И все же, я хочу понять что написано в .LST и зачем? Как пользоваться данными, которые там описаны?
10
24 июня 2013 года
Freeman
3.2K / / 06.03.2004
Это не "внутренняя переменная компилятора", а больше похоже на таблицу символов объектного файла. Чтобы проверить предположение, нужно смотреть спецификацию OMF. Предлагаю автору темы проделать это самостоятельно. Беглый поиск по Википедии вселяет уверенность.
349
25 июня 2013 года
Phantom-84
656 / / 27.10.2005
Я имел в виду результирующий исполняемый файл.
76K
25 июня 2013 года
brudor
27 / / 17.04.2013
Прилепил. И все же, неужели придется разобрать 100 страниц спецификации, чтобы понять как работает ассемблер и как собирается .OBJ? Мож есть где в общих чертах написано, как это работает и что за говорят данные в .LST?
Прикрепленные файлы:
791
Загрузок: 1.4K
260
25 июня 2013 года
Ramon
1.1K / / 16.08.2003
Вам уже все разжевали, на блюдечко положили, а Вам все мало.
Предлагаю монетизировать дальнейшие консультации.
349
25 июня 2013 года
Phantom-84
656 / / 27.10.2005
Посмотрел бинарник. Как я и говорил, реально имеем один сегмент со след. структурой:
1) 100h байт данных;
2) код;
3) данные.
Со стеком проблема: хотя указатель записан верный (0r:0, т.е. стек должен находиться в вершине программного сегмента, что соответствует модели tiny), поле MINMEMSIZE обнулено, поэтому в случае небольшого количества памяти (меньше 64 кб), доступного программе, могут наблюдаться реальные глюки.

Во всем остальном бинарник вроде бы корректен: @data установлен в 0r (я даже не ожидал, что получится это сделать успешно), релок на него в 0r:101h, offset msg установлен в 110h, точка входа в 0r:100h.

Вывод: для исполняемых файлов в формате exe использовать small и т.п. модели памяти.
76K
25 июня 2013 года
brudor
27 / / 17.04.2013
Цитата: Ramon
Предлагаю монетизировать дальнейшие консультации.


Я, вроде как, задал конкретный вопрос: Как разобраться в том что написано в .LST файле. Четкого ответа кроме как почитать спецификацию не увидел, поэтому и мало. А в чем, собственно, проблема?

326
26 июня 2013 года
sadovoya
757 / / 19.11.2005
Об основных принципах работы ассемблеров можно почитать это. И на это полезно взглянуть. Об идентификаторах (@xxx) tasm - здесь.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог