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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 01.07.2021, 20:03   #21
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 624
По умолчанию

А можно ли как-то обратиться напрямую к вот этим байтам регистра?
Изображения
Тип файла: jpg изображение_2021-07-01_200310.jpg (69.0 Кб, 0 просмотров)
Kronos913 вне форума Ответить с цитированием
Старый 01.07.2021, 20:10   #22
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Напрямую к отдельным байтам регистр EAX никак не обратиться.
либо сдвиги shr либо перестановка байт bswap
Либо сохранить в память, а потом прочитать 1 байт movz
А так обычно этого не требуется.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 01.07.2021, 20:25   #23
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 624
По умолчанию

Чтобы было понятнее: задача превратить в числовую переменную последние 4 байта строки. Применяя к ним UpCase. Я уже в другой теме это писал. И решение нашлось

Но вот думаю, может через asm можно сделать более эффективный код? Чтобы по байтам записать в регистр
Kronos913 вне форума Ответить с цитированием
Старый 01.07.2021, 21:20   #24
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Чтобы было понятнее: задача превратить в числовую переменную последние 4 байта строки. Применяя к ним UpCase. Я уже в другой теме это писал. И решение нашлось

Но вот думаю, может через asm можно сделать более эффективный код? Чтобы по байтам записать в регистр
Надо делать LowerCase так как заглавные символы встречаются реже то должно быть быстрее.

Вычитывать надо сразу 4 байта без цикла. Строки содержат хвостовой 0 дополненный до границы в 4 байта. Так что выхода за границу боятся не стоит.

Что касается как разом увеличить уменьшить 4 байта то не проблема. Взглянем на таблицу Ascii


Заглавные буквы имеют бинарные коды
100xxxx
101xxxx
Прописные буквы имеют бинарные коды
110xxxx
111xxxx

Допустим будем увеличивать нам нужно будет отнять 10 0000 = 20h
А бинарные коды
110хххх
111хххх
Нужно превратить 1 а все остальные коды в 0
Легко подобрать формулу (ch shr 6) and (ch shr 5)
Если мы подставим в место 1 буквы регистр eax с 4 буквами и умножим на 20h
((EAX shr 6) and (EAX shr 5) and 01010101h)*20h
То мы получим число которое надо вычесть. Там где у нас был 0 то там будет вычитание 0 а где 1 там вычитание 20h и символ изменится с прописных на заглавные.

Сделаем оптимизацию будем умножать на 2, соответственно маска изменится, и сдвиги.

((EAX shr 2) and (EAX shr 1) and 10101010h)*2h
А умножение можно сделать через сложение или сдвиг

Код:
MOV eax, str   // загружаем из строки её адрес в eax 
test eax,0       // проверяем на nil
jz @exit
add  eax,[eax-4] // Прибавляем длину строки
sub  eax,4 // вычитаем 4
mov eax,[eax] // вычитываем 4 крайних символа 
mov ecx,eax    // сохраняем данные в регистры
mov edx,eax
shr ecx,2
shr edx,1
and ecx.edx
and ecx,10101010h
shl ecx, 1  // умножаем на 2
sub eax, ecx   // вычитаем
@exit:
Писал прям тут без отладки, и проверки
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 02.07.2021, 01:39   #25
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 624
По умолчанию

А где находится код этого фрагмента? Что-то ничего похожего не видно

Цитата:
Сообщение от Pavia Посмотреть сообщение
Надо запустить проект под отладчиком. Ставишь бряк в нужном месте Alt+F8 запускаешь код F9. Затем открываем окно с дизассемблером Ctrl+shift+C или через меню view-> debug windows -> cpu.
Изображения
Тип файла: png изображение_2021-07-02_013915.png (49.3 Кб, 25 просмотров)
Kronos913 вне форума Ответить с цитированием
Старый 02.07.2021, 02:26   #26
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,869
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
А где находится код этого фрагмента?
Ваш "бряк" (брейкпойнт) не валиден. Возможно вы реализовали в некоем модуле данную процедуру, но нигде в коде программы её не вызываете.
P.S. Имхо прежде чем осваивать ассемблер изучите Дельфи. Хотя бы как инструмент разработки программ.

Последний раз редактировалось BDA; 02.07.2021 в 21:00.
northener вне форума Ответить с цитированием
Старый 02.07.2021, 02:36   #27
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
но нигде в коде программы её не вызываете
Да дельфи просто соптимизировал (выбросил) весь код, так как i никем не используется. Валидное место для брейкпоинта (там где синие точки) осталось только на строке с end (которая делает ret из процедуры). Даже странно, что удалось вызвать окно CPU при несработавшем брейкпоинте. Kronos913, брейкпоинт сработает до выполнения кода, на строке которого стоит брейкпоинт. Так что смысла ставить брейк на begin нет, только если не хотите изучать пролог процедуры.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 02.07.2021, 02:58   #28
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,869
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Да дельфи просто соптимизировал (выбросил) весь код, так как i никем не используется.
Да согласен. Не заметил что i локальная переменная.
Цитата:
Сообщение от BDA Посмотреть сообщение
Валидное место для брейкпоинта (там где синие точки) осталось только на строке с end
Но тогда и begin тоже должен быть валидным местом. Вход в процедуру не менее важен чем выход из неё.

Хотя только сейчас задумался о том что означают эти синие точки?

Последний раз редактировалось BDA; 02.07.2021 в 20:59.
northener вне форума Ответить с цитированием
Старый 02.07.2021, 03:25   #29
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Синие точки означают валидные места для брейкпоинтов - строки исходного кода, для которых был сгенерирован ассемблерный код. Процедура выродилась в одну команду ret, а asm-код, как я понимаю, может относиться только к одной строке (точнее, одному оператору) исходного кода, поэтому брейкпоинт можно поставить на end (ret относится к нему), но нельзя на begin.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 08.07.2021, 19:51   #30
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 624
По умолчанию

1. Вызвал я функцию
Код:
call length(s)
Вопрос: а куда записалось значение функции? Как мне переместить его в eax?

2. Вопрос к обращению к одному байте регистра. Можно ли как-то передать один символ строки в один байт регистра, а не в весь регистр?

Код:
mov s[1], al
выдает ошибку

Последний раз редактировалось Kronos913; 08.07.2021 в 20:00.
Kronos913 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Несколько вопросов Rost93 PHP 18 19.09.2012 19:38
Несколько вопросов shrek1993 Visual C++ 3 05.08.2012 18:53
несколько вопросов по C Horus92 Общие вопросы C/C++ 2 15.11.2009 16:08
несколько вопросов fitc Общие вопросы Delphi 28 14.07.2009 21:20
Несколько Вопросов Дорст Общие вопросы Delphi 3 12.11.2007 09:18