Помощь - Поиск - Пользователи - Календарь
Полная версия: Локальная переменная в Pas
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер
Local
Привет!!


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;


Вот объясните почему Я промахиваюсь при вызове локальной перменной в
процедуре с параметрами sad.gif
заранее спасибо
Local
Я уж по всякому пробавал
 mov ax,seg(Pr)
{ или }
mov ax,seg(Pr(Str))
Dark
Все очень просто, твоя строка хранится встеке, а переменная @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;
Local
Цитата(Dark @ 12.05.04 17:00)
Все очень просто, твоя строка хранится встеке, а переменная @Data хранит Data сегмент паскалевской проги(заметь, не ПРОЦЕДУРЫ!)

Большая просьба - востанавливать DS, а то иначе ты изменяешь адрес расположения данных ВСЕЙ программы!!!!

1/@data хранит сегмент начала данных или точку входа в программу huh.gif
наверно сегмент данных потомучто к глобальным доступ беспромблем

2/остается непонятно почему нужно сохрянять в стеке DS и почему
теперь не настаивается сегмент данных DS на начало сегмента
тоесть через SS

3/можно по подробнее а то никак не ухвачу мысль
ведь в стек можно положить не одну переменную


4/а-а-а- стоп кажись понял
DS настраивается на начало стека ведь SS это сегмент стека
т.е.
5/lea dx,Str это мы по стекку гуляем
я правильно понял или нет


P/S/ киньте меня куданить где об этом пишеть
я имею ввиду использование ASM внутри PASCAL
FreeMan
2) не рекомендуеться менять значение сегментных регистров.
З.Ы. что-то я видел форуме раздел "АЗЫ" - там посмотри!
BlackShadow
FreeMan, надо просто по-осторожнее это делать, а по возможности вообще избегать.
И в "АЗАХ", единственная функция, которая должна работать нормально (быстро и качественно) - StrLen, сохраняет DS.
DS хранит то значение, от которого отталкивается компилятор при адресации глобальных переменных. Т. е. сбив его, всепопытки изменить какую-нибудь твою переменную приведёт к изменению данных где-то там.
Далее. Параметры функций адресуются по SS, который далеко не обязательно совпадает с DS => смещение переменной Str надо отсчитывать от SS, поэтому и меняется DS (хотя PUSH SS/POP DS по-моему шустрее и не сбивает AX, но это так, на будующее).
Dark
Цитата
(хотя PUSH SS/POP DS по-моему шустрее и не сбивает AX, но это так, на будующее)


pop


                                Clocks                 Size
       Operands         808x  286   386   486          Bytes

       segreg            8     5     7     3             1


push


                                Clocks                 Size
       Operands         808x  286   386   486          Bytes

       segreg          10/14   3     2     3             1


move

                                Clocks                 Size
       Operands         808x  286   386   486          Bytes

       segreg,reg16      2     2     2     3             2
       reg16,segreg      2     2     2     3             2



Я УБЕДИЛ? согласен smile.gif что на современных компутерах это почти уже не так,
но все таки на push pop уходит больше времени :D (ну... :p2: по крайней мере на 386... lol.gif)

На тему не одной переменной
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;


ЗЫ я тут файлик прекрепил, intel.doc - старенький конечно =) но все же...(rar3)
Dark
Local, в 5 пункте правильно - тока не гуляем, а грузим смещение ;)
Shadow
Здоровеньки!!!
--------------------------------------
почитал Ваш горячий спор
и вот решил выдать инфу насчет оптимизации программы на ASM под
семейство микропроцессоров P6(Pentium Pro II/III)
учитывая особенности ковейера данных процессора команда выбирается
на конвейер устройством выборки команд, которое помещает их в устройство декодирования , состоящее из трех паралельно работающих декодеров 2а простых
1 сложныхю..
Декодеры преобразуют команды микропроцессора в микрооперации
представляющие собой примитивные команды которые выполняютя 5-ю работающими
паралельными исполнительными устройствами микропроцессора .... ну и так далее
.....
Для достижения наибольшей производительности работы декодеров необходимо чтобы на их входы поступали команды декодируемые 6 микрооперациями

-------------
некоторые команды декодируются 1 микрооперацией
а некоторые >4
-------------
в последовательности 4+1+1
==========================================
ню дак вот smile.gif расширенные регистры рассматиривать не будем там для 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
-------------------------------------------

так что MOV и для современных компов работает быстрее

возможно Я и ошибаюсь может есть новая технология, есть еще например
предсказания когда процессор анализ код и на основе этого предсказывает след команду если предсказать не удалось то идет момент синхронизации - может не точно

ню Я тут не полность привел

и вообще чем меньше команд тем медленнее получается это верно для
определенного размера программы у меня даже пример где-то есть
Guest
Можно так:
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.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.