Почему смещение именно такое?
.data
msg db 'Hello $'
.code
start:
mov ah,09h
mov dx, offset msg
int 21h
mov ah, 4Ch
int 21h
end start
lea dx,msg
P.S. DS на данные можно настроить так еще:
mov ds,ax
;этой программе стек и данные не нужны
.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
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
Я проверил. Физический адрес начала data и code отличается на 10h. Все как Вы и говорили, действительно линковка в exe и получаем, что ds указывает на сегмент с PSP. И все бы хорошо, но после пересылки в ds адрес сегмент данных лежит не по нулевому смещению, по нулевом лежит черти-че.
.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
sadovoya, интересный пример, спасибо! Одна непонятка: Я могу менять содержимое сегментных регистров в com-программе, но как только я написал
mov ds, ax
mov ds,ax
Это вполне естественно. Во-первых, в tiny код всегда идет на первом месте, а во-вторых, если ты использовал что-то типа org 100h, то в начало сегмента могут быть вставлены 100h байт данных.
mov ds, ax
mov ds,ax
Опять все вполне естественно. В tiny все объединяется в один сегмент, причем код, как я уже говорил, идет на первом месте, т.е. в лучшем случае ты сможешь обратиться в exe-шнике к @code. В com-файле подобных сегментных адресов не должно быть вообще, потому что никаких релоков там и в помине нет. Естественно, если использовать обычную константу в качестве сегментного адреса, все будет работать, т.к. ассемблер/компоновщик никак по-особому такие адреса не обрабатывает.
Понимаете в чем дело, я не вполне понимаю как работает ассемблер и линкер и хочу в этом разобраться. Вот код:
.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
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
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
??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
DGROUP Group
_DATA 16 0007 Word Public DATA
_TEXT 16 0010 Word Public CODE
"@- это получение адреса, как понять" - никак . это не получение адреса , а имя внутренней переменной компилятора .
"Я могу менять содержимое сегментных регистров в 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
компилятор очень сильно надеется на ваши мозги :) , потому и не ругается .
"@- это получение адреса, как понять" - никак . это не получение адреса , а имя внутренней переменной компилятора .
Что такое внутренняя переменная компилятора?
Phantom, вы имели в виду .MAP? Вот он, если что:
00000H 0010FH 00110H _TEXT CODE
00110H 00116H 00007H _DATA DATA
Program entry point at 0000:0100
Warning: No stack
Предлагаю монетизировать дальнейшие консультации.
1) 100h байт данных;
2) код;
3) данные.
Со стеком проблема: хотя указатель записан верный (0r:0, т.е. стек должен находиться в вершине программного сегмента, что соответствует модели tiny), поле MINMEMSIZE обнулено, поэтому в случае небольшого количества памяти (меньше 64 кб), доступного программе, могут наблюдаться реальные глюки.
Во всем остальном бинарник вроде бы корректен: @data установлен в 0r (я даже не ожидал, что получится это сделать успешно), релок на него в 0r:101h, offset msg установлен в 110h, точка входа в 0r:100h.
Вывод: для исполняемых файлов в формате exe использовать small и т.п. модели памяти.
Я, вроде как, задал конкретный вопрос: Как разобраться в том что написано в .LST файле. Четкого ответа кроме как почитать спецификацию не увидел, поэтому и мало. А в чем, собственно, проблема?