|
Вопрос # 3 874/ вопрос открыт / |
|
Приветствую, уважаемые эксперты!
Это снова я.
На это раз моя проблема заключается втом что команда movsb, вместо копирования символа в регистр DI перенаправляет программу на какой то левый код. Почему понять не могу.
Смысл программы заключается в следующем:
программа копирует символы из строки s1 в строку s2 начиная с символа n+1, количество копируемых символов задается переменной
kolvo?, после чего выводит в поле Edit4 значение строки s2.
Весь файл проекта на delphi и ассемблере прикрепил в файле.
Надеюсь мне помогут разобраться с этим вопросом заранее спасибо.
К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)
Приложение: Переключить в обычный режим- COPY.asm
- =======================================
- <code language=asm>
- title COPY for 32 bits
-
- .386P
- .MODEL FLAT,STDCALL
-
- .DATA
- EXTRN s1:BYTE,S2:BYTE
- EXTRN N:word, KOLVO:WORD
-
- .CODE
-
- PUBLIC COPY
- COPY PROC
- PUSHA
- PUSH DS ;ES=DS
- POP ES ;
-
-
-
- PUSH ECX
-
-
-
-
- next:
-
-
-
-
- mov ax,KOLVO
-
- POP ECX
- POPA
- ret
- COPY ENDP
- {{code|asm}}
 |
Вопрос задал: SOA (статус: Посетитель)
Вопрос отправлен: 11 марта 2010, 19:29
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: Паровоз
Здравствуйте, SOA!
Ваша процедура должна выглядеть примерно так:
PUSHA
CLD
mov eax,[s1]
lea esi,[eax]
mov eax,[s2]
lea edi,[eax]
PUSH ECX
mov ecx,N
dec ecx
rep lodsb
mov ecx,KOLVO
rep movsb
POP ECX
POPA
ret
А использовать ее нужно примрно так:
s1:=Edit3.Text;
n:=StrToInt(Edit1.Text);
KOLVO:=StrToInt(Edit2.Text);
SetLength(s2,KOLVO);
COPY();
Edit4.Text:=s2;
 |
Ответ отправил: Паровоз (статус: 10-ый класс)
Время отправки: 12 марта 2010, 00:06
|
Мини-форум вопроса
Всего сообщений: 6; последнее сообщение — 12 марта 2010, 12:52; участников в обсуждении: 3.
|
Вадим К (статус: Академик), 11 марта 2010, 21:14 [#1]:
А Вы точно уверены, что работать со строками можно именно так, как Вы работаете?
Адрес переменной типа string не является началом строки.
Но другая ошибка в том, что нельзя писать так просто по тому адресу, где находиться строка.
Почему программа переходит по другому адресу? да дело в том, что Вы перетираете данные. Она и диск форматнуть может, если чего...
Итого. если переменную типа string надо прочитать, то в ассемблерном коде это должен быть не byte, а как минимум dword. и в нем храниться адрес начала строки в памяти, а по адресу минус 4 байта находиться длина строки. по адресу минус 8 байт находиться счетчик ссылок.
Но вот если читать строку можно, модифицировать символы тоже можно, то удлинять строку без обращений к менеджеру памяти - нельзя. Чревато различными спецэффектами.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Паровоз (статус: 10-ый класс), 11 марта 2010, 23:46 [#2]:
То, что Вы делаете просто ужасно. Вы бы почитали сначала про организацию строк в Delphi. Переменнная типа string это указатель на область памяти, в которой размещается строка. Кроме того, нулевой байт строки давно не содержит ее длины (это было в каменном веке), а под саму строку s2 нужно сначала выделять памсять.
Я не говорю уже о том, что все указатели давным давно 4-х байтовые. Поэтому загрузка строки в ESI, например, должна выглядеть так:
mov eax,[s1]
lea esi,[eax]
|
|
Паровоз (статус: 10-ый класс), 12 марта 2010, 07:25 [#3]:
P.S. Совсем забыл, вместо pusha/popa нужно использовать pushad/popad.
|
|
SOA (статус: Посетитель), 12 марта 2010, 10:11 [#4]:
Видите ли примеры в книге по которой я учусь описывают взаимодействие asm и pascal, или C++.
Я всего лишь пытаюсь адаптировать эти примеры для взаимодействия с delphi в силу своих знаний и умений и не претендую на звание эксперта.
Информация по формату строк в delphi довольно интересна, но к сожелению я ее не встречал(в стандартном helpe видел разве что количество байт выделяемое по тот или иной тип), поэтому не могли бы вы указать в каких источниках можно посмотреть информацию такого рода по delphi в целом(книга или еще чтонибудь), также буду признателен, если подскажете какую нибудь книгу по asm32.
По ответу хотел бы сказать: конечно интересно, но дело втом что delphi я использую только для интерфейса, не могли бы вы показать как в asm32 указывается длина строки без использования delphi, чтоб я смог поставить заслуженную оценку.
|
|
Паровоз (статус: 10-ый класс), 12 марта 2010, 11:12 [#5]:
"delphi я использую только для интерфейса"
Вы приняли неправильное решение. Все это напоминает сагу о X,Y Z: я хочу получить X. Как мне сделать Y (http://gunsmoker.blogspot.com/2008/10/x-y-z.html).
Если Вы хотите программировать под DOS, так и делайте это. Не сидите между двумя стульями. Программирование под DOS и под Windows - совершенно разные вещи. Выберете что-нибудь одно, а иначе Вы будете не только путать отвечающих Вам, но и обманите сами себя.
В Delphi для управления строками используется специальный менеджер, который в свою очередь опирается еще на один менеджер - менеджер динамической памяти. На ассемблере Вам это пока не потянуть. А если Delphi используется только для интерфейса, то вникать в такие сложные темы просто не имеет смысла.
Определитесь сначала сами. Если Вам нужен просто Паскаль, ну так и используйте Turbo Pascal. А если Вы хотите использовать для интерфейса Delphi, то создавайте строку с помощью SetLength (как показано на примере) и не заморачивайтесь.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|