Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.06.2012, 15:01   #1
.:DEZ:.
Пользователь
 
Регистрация: 03.06.2012
Сообщений: 28
Вопрос

Всем привет. есть такое задание: Задана строка символов. Составить программу, выясняющую, имеется ли в ней все буквы из другого заданного слова. Причём порядок наличия символов в проверяемой строке должен быть обратным их порядку во второй строке. Строки задаются с клавиатуры.

я написал прогу на паскале:
Код:
Program zadacha;
uses crt;
var
S1,S2,S3,L1,L2,L3: string;
i,j,n,m,k: integer;
begin
Clrscr;
 Writeln('Введите первую строку');
 Readln(S1);
 Writeln('Введите вторую строку');
 Readln(S2);
 i:= Length(S1);
  While i>0 do
    begin
     L1:= Copy(S1,i,1);
     S3:= Concat(S3,L1);
     i:=i-1;
    end;
 
  n:= Length(S2);
  For j:=1 to n do
   begin
     L2:= Copy(S2,j,1);
     m:= Pos(L2,S3);
     If m>0 then
      Begin
       L3:= Concat(L3,Copy(S3,m,1));
       Delete(S3,1,m) ;
      end;
   end;
  k:= Length(L3);
 If n=k then
 Writeln('Есть такое слово ',L3)
  else
 Writeln('Нет такого слова ','нашлось только ',L3);
end.
Всё работает правильно, теперь её нужно перевести на ассемблер, у меня есть кое-какие наброски, я только начал изучать ассемблер, поэтому плохо понимаю как всё это связать помогите пожалуйста.

вот наброски:
Код:

.MODEL tiny
.486p
.code
assume cs:@code, ds:@code, es: @code, ss: @code
 org 100h
start:
 JMP main
 str1 db 'Vvedite pervuiu stroku',13,10
Len_str1=$-str1
str2 db 'Vvedite vtoruiu stroku',13,10
len_str2=$-str2
Str3 db 100 dup(?)
MAIN:

;_____цикл while
 
begin_loop:
        cmp i, 0
        jng end_loop
        pushd  1
        push i
        push S1
        call Copy
        add esp, 12
        mov L1, eax
        push L1
        push S3
        call  Concat
        add esp, 8
        mov S3, eax
        dec i
        jmp begin_loop
end_loop:
; переменные передаваемые функциям, определены, например, так i equ dword ptr [ebp+4]

;_________функция copy
lea si, S1 
lea di, i 
cld
mov cx,1 
rep movsb 
mov i,1


;_________concat
Concat для нультерминатных строк:

Вход:s1,s2 - адреса нультерминатных строк для совмещения, s3 - адрес строки, где будет результат. Выход: по адресу s3 - нультерминатная соединенная строка.
Код:
Concat proc S1:word,S2:word,S3:word
mov si,s1
mov di,s3
loopch:
lodsb 
cmp al,0
je uval
stosb
jmp loopch
uval:
mov si,s2
loopch1:
lodsb 
cmp al,0
je uval1
stosb
jmp loopch1
uval1:
mov al,0
mov [si],al
ret
Concat endp
знающие люди, помогите кто-нибудь

Последний раз редактировалось Stilet; 03.06.2012 в 20:03.
.:DEZ:. вне форума Ответить с цитированием
Старый 04.06.2012, 08:06   #2
.:DEZ:.
Пользователь
 
Регистрация: 03.06.2012
Сообщений: 28
По умолчанию

.:DEZ:. вне форума Ответить с цитированием
Старый 04.06.2012, 08:22   #3
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Я бы поступил следующим образом.
Откомпилировал прогу, а затем дизасемблировал экзешник.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder

Последний раз редактировалось Smitt&Wesson; 04.06.2012 в 08:25.
Smitt&Wesson вне форума Ответить с цитированием
Старый 04.06.2012, 08:33   #4
.:DEZ:.
Пользователь
 
Регистрация: 03.06.2012
Сообщений: 28
По умолчанию

Цитата:
Сообщение от Smitt&Wesson Посмотреть сообщение
Я бы поступил следующим образом.
Откомпилировал прогу, а затем дизасемблировал экзешник.
Я пробовал так делать, там ничего вообще не понятно я поэтому и стал так писать, вот где то половину сделал и запутался, помогите до конца её доделать.



как вот этот цикл будет выглядеть?

For j:=1 to n do
begin
L2:= Copy(S2,j,1);
m:= Pos(L2,S3);
If m>0 then
Begin
L3:= Concat(L3,Copy(S3,m,1));
Delete(S3,1,m) ;
end;
end;


Последний раз редактировалось Stilet; 10.06.2012 в 09:38.
.:DEZ:. вне форума Ответить с цитированием
Старый 05.06.2012, 16:28   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

я бы начал с того, что переписал бы исходную программу на паскале, хотя бы так.

Потому что тот ужос, который есть, не то что на ассемблер, а и на обычный язык трудно перевести.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 05.06.2012, 17:39   #6
.:DEZ:.
Пользователь
 
Регистрация: 03.06.2012
Сообщений: 28
Восклицание

спасибо, но прога не совсем правильно работает:
например вводим слово "Привет", затем слово "тт" и он говорит что имеется, хотя там только одна буква т
.:DEZ:. вне форума Ответить с цитированием
Старый 05.06.2012, 18:00   #7
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

ага, чуток исправил
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 05.06.2012, 18:44   #8
.:DEZ:.
Пользователь
 
Регистрация: 03.06.2012
Сообщений: 28
Радость

вот сейчас правильно вы хитро сделали, спасибо вам, но мне чего то не понять как на ассемблер перевести это

veniside, можете с переводом помочь?

Последний раз редактировалось Stilet; 10.06.2012 в 09:42.
.:DEZ:. вне форума Ответить с цитированием
Старый 05.06.2012, 19:16   #9
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

вот если честно, то лень )
Но, когда мы убрали все эти ужасные Pos(), Concat() и прочие операции с текстом, перевод должен быть достаточно прямолинейным. ReadLn()/WriteLn() я не привожу, а на остальное дельфовый дизассемблер выдал такое:

Код:
  p1 := length(s1) + 1;
00407118 A194BB4000       mov eax,[$0040bb94]   // это S1 (указатель на строку)
0040711D 85C0             test eax,eax   // указатель пуст? (пустая строка?)
0040711F 7405             jz $00407126   // если да, то в eax уже 0 как длина, переходим чуть дальше
00407121 83E804           sub eax,$04   // иначе смещаемся на 4 байта назад, там дельфи хранит длину строки
00407124 8B00             mov eax,[eax]   // загружаем длину
00407126 8D5801           lea ebx,[eax+$01]   // другими словами EBX := EAX + 1, кстати, EBX у нас вместо P1

  p2 := 1;
00407129 BE01000000       mov esi,$00000001   // ну понятно, ESI будет вместо P2
0040712E EB29             jmp $00407159   // заходим в первый while

  dec(p1);
00407130 4B               dec ebx   // ага

  while (1 <= p1) do
00407131 83FB01           cmp ebx,$01   // зашли во второй while, проверяем условие
00407134 7C1D             jl $00407153   // обходим while, если условие не выполнено

  if (s1[p1] = s2[p2]) then
00407136 A194BB4000       mov eax,[$0040bb94]   // это S1 (указатель)
0040713B 0FB74458FE       movzx eax,[eax+ebx*2-$02]   // EAX := S1[P1]
00407140 8B1598BB4000     mov edx,[$0040bb98]   // это S2 (указатель)
00407146 663B4472FE       cmp ax,[edx+esi*2-$02]   // сравниваем AX и S2[P2]
0040714B 7406             jz $00407153   // если равно, выходим из while по break;

  dec(p1);
0040714D 4B               dec ebx   // иначе двигаемся по строке

  while (1 <= p1) do
0040714E 83FB01           cmp ebx,$01   // проверка условия (дубль :)
00407151 7DE3             jnl $00407136   // уходим на новый внутренний while цикл

  if (1 > p1) then
00407153 83FB01           cmp ebx,$01   // пора выходить из внешнего while?
00407156 7C0F             jl $00407167   // ага

  inc(p2);
00407158 46               inc esi   // ага

  while (p2 <= length(s2)) do begin
00407159 A198BB4000       mov eax,[$0040bb98]   // проверка условия внешнего while
0040715E E83DDEFFFF       call @UStrLen   // зачем-то вызов функции длины строки, хотя длина строки есть рядом (на 4 байта назад, как сделано в начале)
00407163 3BF0             cmp esi,eax   // пора выходить из внешнего while?
00407165 7EC9             jle $00407130   // если нет, то уходим на очередной цикл

  if (1 > p1) then
00407167 4B               dec ebx  // конечная проверка, какой WriteLn вызвать
00407168 7D1B             jnl $00407185 // переход, если P1 не меньше 1
я там прокомментировал что к чему, чтобы было понятней.

Update: Есть такой момент, что у меня юникодная Дельфи, т.е. каждый символ занимает 2 байта. У вас наверно 1 символ = 1 байт, так что вместо такого:

Код:
00407146 663B4472FE       cmp ax,[edx+esi*2-$02]   // сравниваем AX и S2[P2]
будет без умножения на 2:

Код:
00407146 663B4472FE       cmp ax,[edx+esi-$01]   // сравниваем AX и S2[P2]
(-1, т.к. нумерация символов в строке начинается с 1)
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 05.06.2012 в 19:29.
veniside вне форума Ответить с цитированием
Старый 05.06.2012, 20:22   #10
.:DEZ:.
Пользователь
 
Регистрация: 03.06.2012
Сообщений: 28
По умолчанию

Огромное спасибо, теперь осталось разобраться в этом. Мне вот эти цифры
не понятны в командах mov eax,[$0040bb94], обычно же так не пишут, когда переводят
.:DEZ:. вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перевод из паскаля на СИ Кот Шрёдингера Помощь студентам 0 02.11.2011 20:07
Перевод с Паскаля на С++.... Solnze2 Помощь студентам 0 20.05.2011 23:13
перевод из паскаля в с++ dANIL282 Помощь студентам 2 21.01.2011 00:05
Перевод с Паскаля на С RamilFaz Общие вопросы C/C++ 3 08.04.2010 14:40
Из паскаля в ассемблер Archiserafim Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 16 03.09.2009 22:02