Привет!!
Procedure Pr(Str : String);
begin
Str:=Str+'$';
asm
mov ax,seg(@Data)
mov ds,ax
xor ax,ax
mov ah,9
mov dx,offset Str
int 21h
end;
end;
BEGIN
Pr('Hello');
asm
mov ah,0
int 16h
end;
End;
Я уж по всякому пробавал
mov ax,seg(Pr)
{ или }
mov ax,seg(Pr(Str))
Все очень просто, твоя строка хранится встеке, а переменная @Data хранит Data сегмент паскалевской проги(заметь, не ПРОЦЕДУРЫ!)
Большая просьба - востанавливать DS, а то иначе ты изменяешь адрес расположения данных ВСЕЙ программы!!!!
Procedure Pr(Str : String);
begin
Str:=Str+'$';
asm
push ds
mov ax,ss
mov ds,ax
xor ax,ax
mov ah,9
lea dx, Str {грузим смещение - Load Effective Address}
inc dx {тожеобрати внимание - Str[0] содержит размер строки, поэтому его вывод нам не интересен}
int 21h
pop ds
end;
end;
2) не рекомендуеться менять значение сегментных регистров.
З.Ы. что-то я видел форуме раздел "АЗЫ" - там посмотри!
FreeMan, надо просто по-осторожнее это делать, а по возможности вообще избегать.
И в "АЗАХ", единственная функция, которая должна работать нормально (быстро и качественно) - StrLen, сохраняет DS.
DS хранит то значение, от которого отталкивается компилятор при адресации глобальных переменных. Т. е. сбив его, всепопытки изменить какую-нибудь твою переменную приведёт к изменению данных где-то там.
Далее. Параметры функций адресуются по SS, который далеко не обязательно совпадает с DS => смещение переменной Str надо отсчитывать от SS, поэтому и меняется DS (хотя PUSH SS/POP DS по-моему шустрее и не сбивает AX, но это так, на будующее).
Clocks Size
Operands 808x 286 386 486 Bytes
segreg 8 5 7 3 1
Clocks Size
Operands 808x 286 386 486 Bytes
segreg 10/14 3 2 3 1
Clocks Size
Operands 808x 286 386 486 Bytes
segreg,reg16 2 2 2 3 2
reg16,segreg 2 2 2 3 2
Procedure Pr(Str,str1 : String);
begin
Str:=Str+'$';
Str1:=Str1+'$';
asm
push ds
mov ax,ss
mov ds,ax
xor ax,ax
mov ah,9
lea dx, Str
inc dx
int 21h
lea dx, Str1
inc dx
int 21h
pop ds
end;
end;
Local, в 5 пункте правильно - тока не гуляем, а грузим смещение ;)
Здоровеньки!!!
--------------------------------------
почитал Ваш горячий спор
и вот решил выдать инфу насчет оптимизации программы на ASM под
семейство микропроцессоров P6(Pentium Pro II/III)
учитывая особенности ковейера данных процессора команда выбирается
на конвейер устройством выборки команд, которое помещает их в устройство декодирования , состоящее из трех паралельно работающих декодеров 2а простых
1 сложныхю.. Декодеры преобразуют команды микропроцессора в микрооперации
представляющие собой примитивные команды которые выполняютя 5-ю работающими
паралельными исполнительными устройствами микропроцессора .... ну и так далее
.....
Для достижения наибольшей производительности работы декодеров необходимо чтобы на их входы поступали команды декодируемые 6 микрооперациями
-------------
некоторые команды декодируются 1 микрооперацией
а некоторые >4
-------------
в последовательности 4+1+1
==========================================
ню дак вот расширенные регистры рассматиривать не будем там для MMX XMM технологии
r8,r16,r32 операндв регистре байт слово 2слово
m8,m16,m32 память
i8,i16,i32 непосредственный операнд
a8,a16,a32 отности операнд смещение в сегменте
------------------------------------------
команда
MOV |со всеми сегментами|,m16 -> 4 мкп
MOV |m16|,ds fs ss cs gs es -> 3 мкп
MOV m8,r8 -> 2
MOV rm16,es fs ss -> 1
MOV rm16/32,i16/32 -> 1
-------------------------------------------
POP ds fs ss -> 4
POP m16/32 -> 4
POP r16/32 -> 2
-------------------------------------------
PUSH cs gs es fs ss -> >4
-------------------------------------------
Можно так:
program Hello;
procedure Print(const s: String);
var
ts: String;
begin
ts := s + '$';
asm
push ds
mov ax,ss
mov ds,ax
lea dx,ts[1]
mov ah,9
int 21h
pop ds
end;
end;
begin
Print('Hello, World!'#13#10);
asm
xor ax,ax
int 16h
end;
end.
program Hello;
procedure Print(const s: String); assembler;
asm
push ds
lds dx,s
inc dx
mov ah,9
int 21h
pop ds
end;
begin
Print('Hello, World!'#13#10'$');
asm
xor ax,ax
int 16h
end;
end.