Консультация № 183608
13.06.2011, 22:36
0.00 руб.
0 3 1
Здравствуйте! У меня возникли сложности с таким вопросом: Уважаемый Игорь Витальевич и другие эксперты! Повторяю свой вопрос за №183348 от 25,05,2011 года- требуется написать 3 варианта заданной подпрограммы ( на встроенном ассемблере, с использованием модели памяти PASCAL (листинг) и без использования директивы MODEL (листинг)). Программу, вызывающую эти подпрограммы с указанием автора и варианта задания . Задание- копирование строк. АСС- TASM.Извините, но в мини-форум в свое время не смог войти. Поэтому отвечаю-речь идет о программе на Паскале, не на С.
Ответ за № 267396 дал Зенченко Константин Николаевич, очень ему благодарен-но второй код с директивой MODEL, а нужен без. Помогите пожалуйста. Прошу помощи в исправлении второго кода и очень необходимы комментарии на каждой строке всех программ.С благодарностью, Canijke

Приложение:
var
a,b,c,d:string;
procedure CopyStrA(var x,y:string);external;
{$L q183348a}
procedure CopyStrB(var x,y:string);external;
{$L q183348b}
procedure CopyStrC(var x,y:string);
begin
asm
cld
lds si,dword ptr x
les di,dword ptr y
lodsb
stosb
mov cl,al
xor ch,ch
rep movsb
end
end;
begin
Writeln('Canijke');
repeat
write('Enter string:');
readln(d)
until length(d)>0;
CopyStrA(d,a);
writeln('Result A:',a);
CopyStrB(d,b);
Writeln('Result B:',b);
CopyStrC(d,c);
writeln('Result C:',c);
readln;
end.


С директивой MODEL и упрощенным описанием сегментов:
Код :
model small,pascal
.code
public CopyStrA
proc CopyStrA
push bp
mov bp,sp
cld
mov di,[bp+04]
mov es,[bp+06]
mov si,[bp+08]
mov ds,[bp+10]
lodsb
stosb
mov cl,al
xor ch,ch
rep movsb
pop bp
ret 8
endp
end


Полное описание сегмента:
Код :
_TEXT segment word public 'CODE'
public CopyStrB
assume cs:_TEXT
proc CopyStrB
push bp
mov bp,sp
cld
mov di,[bp+04]
mov es,[bp+06]
mov si,[bp+08]
mov ds,[bp+10]
lodsb
stosb
mov cl,al
xor ch,ch
rep movsb
pop bp
ret 8
endp
_TEXT ends
end

Обсуждение

давно
Посетитель
7438
7205
14.06.2011, 00:08
общий
Здравствуйте.
Вы не можете попасть в мини-форум вопроса? Странно... Ладно, разберемся.
Можете писать мне в личку. Я перенесу в мини-форум.
Несколько вопросов:
1) Предыдущий вопрос №183604 я удаляю за ненадобностью
2) В ответе три текста:
а) программа на Паскале с процерурой на встроенном ассемблере и вызовом этой и еще двух других
б) подпрограмма на Ассемблере с директивой MODEL
в) подпрограмма на Ассемблере без директивы MODEL. Именно она Вам и нужна Или нет?
Так что, все есть. Осталось только прокомментировать.
Так или не так?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
14.06.2011, 11:32
общий
Сообщение от Сanijke:

Да. нужны только построчные комментарии. С нетерпением жду ответа.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
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]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа