14.06.2011, 12:37
общий
это ответ
Здравствуйте, Сanijke!
Вот Вам прокомментированные тексты.
Вы зарегистрировались как "Посетитель - 377629". Это правильно.
Рекомендую переименоваться в Canijke и в будущем задавать вопросы под этим ником.
Дело в том, что временная регистрация - она и есть временная, только для ознакомления.
Работать с ней очень неудобно.
Будут вопросы, пишите в личку. С посетителя Вы не сможете написать в "чужую" консультацию...
Код на Паскале:
[code h=207]{строки, используемые в программе}
var
a,b,c,d:string;
{внешние подпрограммы}
procedure CopyStrA(var x,y:string);external;
{подгружаем внешний модуль q183348a.obj}
{$L q183348a}
procedure CopyStrB(var x,y:string);external;
{подгружаем внешний модуль q183348b.obj}
{$L q183348b}
{процедура со встроенным Ассемблером}
{параметры: x-исходная строка, y-выходная}
procedure CopyStrC(var x,y:string);
begin {начало процедуры}
asm {задаем включение блока на асме}
cld {задаем автоинкремент для строковых команд}
lds si,dword ptr x {загружаем длинный адрес исходной строки в ds:si}
les di,dword ptr y {загружаем длинный адрес выходной строки в es:di}
lodsb {первый байт-длина строки, al = ds:[si], si=si+1}
stosb {сохраняем es:[di] = al, di=di+1}
mov cl,al {длина строки в счетчик cx}
xor ch,ch {байт превращаем в слово}
rep movsb {копируем в повторе cx байт строки es:[di]=ds:[si], si=si+1, di=di+1}
end {конец блока на асме}
end; {конец процедуры}
begin {начало программы}
Writeln('Canijke, 5 variant');{автор}
repeat {ждем, пока не введем непустую строку}
write('Enter string:'); {приглашение на ввод}
readln(d) {читаем с консоли/клавиатуры}
until length(d)>0; {проверяем, чтобы была непустая строка}
CopyStrA(d,a); {вызываем процедуру со встроенным Ассемблером, a=d}
writeln('Result A:',a); {выводим результат}
CopyStrB(d,b); {вызываем процедуру, которая описана с MODEL, b=d}
Writeln('Result B:',b); {выводим результат}
CopyStrC(d,c); {вызываем процедуру, которая описана без MODEL, c=d}
writeln('Result C:',c); {выводим результат}
readln; {ждем нажатия на Enter, чтобы окно не закрылось сразу}
end. {конец программы}
[/code]
С директивой MODEL и упрощенным описанием сегментов:
[code h=207]model small,pascal ;модель памяти и способ передачи параметров
.code ;сегмент кода
public CopyStrA ;имя будет вызываться из другого модуля
proc CopyStrA ;имя процедуры
push bp ;сохраним регистр, с его помощью будем адресовать параметры
mov bp,sp ;в bp кадр стека
cld ;задаем автоинкремент для строковых команд
;загрузим адреса строк, которые является длинными указателями
mov di,[bp+04] ;адрес в кадре стека для смещения выходной строки
mov es,[bp+06] ;адрес в кадре стека для сегмента выходной строки
mov si,[bp+08] ;адрес в кадре стека для смещения исходной строки
mov ds,[bp+10] ;адрес в кадре стека для сегмента исходной строки
lodsb ;первый байт-длина строки, al = ds:[si], si=si+1
stosb ;сохраняем es:[di] = al, di=di+1
mov cl,al ;длина строки в счетчик cx
xor ch,ch ;байт превращаем в слово
rep movsb ;копируем в повторе cx байт строки es:[di]=ds:[si], si=si+1, di=di+1
pop bp ;восстанавливаем содержимое bp
ret 8 ;выход из подпрограммы с удалением из стека параметров - 4 слов
endp ;конец процедуры
end ;конец модуля
[/code]
Полное описание сегмента:
[code h=207]_TEXT segment word public 'CODE';сегмент кода
public CopyStrB ;имя будет вызываться из другого модуля
assume cs:_TEXT ;связываем сегментный регистр с сегментом кода
proc CopyStrB ;имя процедуры
push bp ;сохраним регистр, с его помощью будем адресовать параметры
mov bp,sp ;в bp кадр стека
cld ;задаем автоинкремент для строковых команд
;загрузим адреса строк, которые является длинными указателями
mov di,[bp+04] ;адрес в кадре стека для смещения выходной строки
mov es,[bp+06] ;адрес в кадре стека для сегмента выходной строки
mov si,[bp+08] ;адрес в кадре стека для смещения исходной строки
mov ds,[bp+10] ;адрес в кадре стека для сегмента исходной строки
lodsb ;первый байт-длина строки, al = ds:[si], si=si+1
stosb ;сохраняем es:[di] = al, di=di+1
mov cl,al ;длина строки в счетчик cx
xor ch,ch ;байт превращаем в слово
rep movsb ;копируем в повторе cx байт строки es:[di]=ds:[si], si=si+1, di=di+1
pop bp ;восстанавливаем содержимое bp
ret 8 ;выход из подпрограммы с удалением из стека параметров - 4 слов
endp ;конец процедуры
_TEXT ends ;конец сегмента
end[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен