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

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

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.05.2013, 22:09   #1
Jawner
Пользователь
 
Регистрация: 11.04.2012
Сообщений: 15
По умолчанию Вставка Assembler.Работа с символами. Проблема с пересылкой символа

Доброго времени суток.
Пишем на C+ Builder 6
По заданию нужно постороить вторую строку символов из матрицы символов 3х4.

Код:


Код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char s[3][4];
AnsiString c;
c.SetLength(4);
for(int i=0; i<3;i++)
for(int j=0; j<4;j++)
s[i][j]=Memo1->Lines->Strings[i][j+1];
asm
{
pusha
mov edi, dword ptr [s]
lea edi, [edi+4]
mov esi, dword ptr [c]
mov ecx,4
next:
mov al,byte ptr [edi]  <-- в этом месте вылетает ошибка(скрин прикрепил)
mov byte ptr[esi],al
lea edi, [edi+1]
inc esi
loop next
popa
}
Edit1->Text=c;
}
Jawner вне форума Ответить с цитированием
Старый 21.05.2013, 11:56   #2
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Код:
lea edi, [edi+4]
Что вот здесь ты пытаешься сделать?

Последний раз редактировалось FataLL; 21.05.2013 в 12:08.
FataLL вне форума Ответить с цитированием
Старый 21.05.2013, 18:11   #3
Jawner
Пользователь
 
Регистрация: 11.04.2012
Сообщений: 15
По умолчанию

Цитата:
Сообщение от FataLL Посмотреть сообщение
Код:
lea edi, [edi+4]
Что вот здесь ты пытаешься сделать?
Смотри, допустим у меня матрица символов такая:
йцук
фыва
ячсм

в команде выше я пытаюсь перейти на символ "ф"
Jawner вне форума Ответить с цитированием
Старый 22.05.2013, 10:04   #4
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Фактически, можно просто прибавить edi 4. Но ошибка в другом
Код:
mov edi, dword ptr [s]
Здесь ты загружаешь не адрес начала массива, как, видимо, хотел сделать, а двойное слово, находящееся по адресу s. Т.е., у тебя в edi загружаются коды символов "йцук" Будь проще
Код:
lea edi, s // правильный вариант
В случае с AnsiString всё правильно
Код:
mov esi, dword ptr [c] // адрес начала строки
Хотя угловые скобки ставить необязательно, они сбивают с толку...
FataLL вне форума Ответить с цитированием
Старый 22.05.2013, 10:06   #5
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Кстати, зачем тебе ассемблер? Спортивный интерес?
Код:
AnsiString c = s[1];
c.SetLength( 4 );
Edit1->Text = c;
И никакого гимора...
FataLL вне форума Ответить с цитированием
Старый 22.05.2013, 22:51   #6
Jawner
Пользователь
 
Регистрация: 11.04.2012
Сообщений: 15
По умолчанию

Цитата:
Сообщение от FataLL Посмотреть сообщение
Фактически, можно просто прибавить edi 4. Но ошибка в другом
Код:
mov edi, dword ptr [s]
Здесь ты загружаешь не адрес начала массива, как, видимо, хотел сделать, а двойное слово, находящееся по адресу s. Т.е., у тебя в edi загружаются коды символов "йцук" Будь проще
Код:
lea edi, s // правильный вариант
В случае с AnsiString всё правильно
Код:
mov esi, dword ptr [c] // адрес начала строки
Хотя угловые скобки ставить необязательно, они сбивают с толку...
Действительно, поменял на lea и все нормально.
ТОлько я что то не понял, почему с AnsiString проблем не было, а c char проблемы ?
А насчет угловых скобок - насколько я понял в них указывается адрес, а в круглых само значение.
Jawner вне форума Ответить с цитированием
Старый 22.05.2013, 22:55   #7
Jawner
Пользователь
 
Регистрация: 11.04.2012
Сообщений: 15
По умолчанию

Цитата:
Сообщение от FataLL Посмотреть сообщение
Кстати, зачем тебе ассемблер? Спортивный интерес?
Код:
AnsiString c = s[1];
c.SetLength( 4 );
Edit1->Text = c;
И никакого гимора...
Ну вообще то мы изучаем ассемблер.
Еще если не сложно объясни пожалуйста зачем SetLength. Насколько я понял это я просто обрезаю строку до 4ех символов для результата, что бы не было всякого мусора из ОЗУ.
Еще момент с s[i][j]=Memo1->Lines->Strings[i][j+1];
зачем j+1 ? не могу понять.
А так же еще не совсем понимаю команды pusha и popa. Это загрузка из стека в флаги, а в конце выгрузка - зачем это делать ?
Jawner вне форума Ответить с цитированием
Старый 23.05.2013, 17:30   #8
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Цитата:
Сообщение от Jawner Посмотреть сообщение
ТОлько я что то не понял, почему с AnsiString проблем не было, а c char проблемы ?
А насчет угловых скобок - насколько я понял в них указывается адрес, а в круглых само значение.
AnsiString - это указатель на указатель. Указатель на экземпляр класса AnsiString, из которого надо взять указатель на строку. Поэтому, dword ptr с означает: "взять адрес, находящийся по адресу с". В случае с массивом ты имеешь просто указатель на начало области памяти 3х4.
Про скобки: ты же не на чистом ассемблере пишешь, а на встроенном. Сначала эти строки обрабатываются компилятором С++. Поэтому есть некоторые расхождения с чистым ассемблером. В данном случае, ставишь скобки или нет - код генерируется один. Почему так? Точнее не могу сказать, экспериментируй.

Цитата:
Сообщение от Jawner Посмотреть сообщение
Еще если не сложно объясни пожалуйста зачем SetLength. Насколько я понял это я просто обрезаю строку до 4ех символов для результата, что бы не было всякого мусора из ОЗУ.
Всё правильно. Хотя и не совсем корректно, так как изначально мусора из ОЗУ может быть очень много.

Цитата:
Сообщение от Jawner Посмотреть сообщение
Еще момент с s[i][j]=Memo1->Lines->Strings[i][j+1];
зачем j+1 ? не могу понять.
Без понятия. Вопрос в том, что хотелось сделать? В данном случае получается, что у тебя копируется 2, 3, 4 и 5 символ строки Memo. Я ж не знаю, что у тебя там было изначально. Но ясно одно, если в Memo строки короче 4 символов, то могут быть проблемы типа EAccessViolation...

Цитата:
Сообщение от Jawner Посмотреть сообщение
А так же еще не совсем понимаю команды pusha и popa. Это загрузка из стека в флаги, а в конце выгрузка - зачем это делать ?
Эти две команды сохраняют (pusha) и восстанавливают (popa) содержимое всех регистров и состояние флагов в (из) стека. Видимо, это сделано для страховки, чтоб ничего не "испортить" для функции. На самом деле, без них можно обойтись, главное не испортить регистры bp и sp. Если предполагается менять их содержимое, то надо позаботиться о восстановлении, как было до входа в твой код.
FataLL вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с символами. Проблема с пересылкой символа Jawner Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 20.05.2013 18:16
Вставка символа Waqq Помощь студентам 4 03.09.2011 21:11
Вставка символа:) WizarD.89 Microsoft Office Excel 13 03.05.2011 21:47