Дан указатель на память (в байтах разумеется) и два индекса бита (младший и старший - относительно указателя на память.) В выходном значении в 0 бите отразить выравнен ли младший индекс по двойному слову (1 - не выравнен) в 1 бите отразить является ли старший бит старшим битом двойного слова. (1 - не является) во 2 бите отразить принадлежат ли оба бита одному и тому же двойному слову. (1 - принадлежат) Нетрудно заметить что бин и унбин в выходном значении отражают принадлежит ли битовый диапозон диапозону выравненому по двойным словам. (т.е. младший бит является битом двойного слова и размер в битах кратен 32ум) Задача разумеется для "крупных" или по крайней мере "пытливых" мозгов, т.е. избегайте (после того как представите мат. лог. модель) тупых чрезмерных проверок. Большое спасибо тем кто учавствует. И не ленитесь писать тесты, опять мне что-ли писать?
-- under construction -- Код (Text): xor eax, eax mov edx, hiindex bts eax, edx mov ecx, loindex xor edx, ecx cmp edx, 32 setalc rol eax, 2 bts eax, ecx пока не идеально ...
Код (Text): index_test:;(index_low +4, index_high +8) xor eax,eax mov edx,[esp+4];i_l and edx,-32 cmp edx,[esp+4] rcr eax,1 mov ecx,[esp+8];i_h or ecx,31 cmp [esp+8],ecx rcr eax,1 xor ecx,edx cmp ecx,32 rcl eax,3 ret 8
А что если указатель на память не выравнен по двойному слову? Вы как то проигнорировали сам указатель.
The Svin Самое простое решение которое я вижу: прибавить два младших бита указателя к индексу бита, сдвинув их на 3 разряда. [delete]Но я не уверен в правильности ответа, если произойдёт переполнение.[/delete] Код (Text): index_test:;(index_low +4, index_high +8, array +12) mov eax,[esp+12] ; and eax,3 - эта команда не нужна shl eax,3 add [esp+4],eax; даже в случае переполнения add [esp+8],eax; ответ будет правильный xor eax,eax mov edx,[esp+4];i_l and edx,-32 cmp edx,[esp+4] rcr eax,1 mov ecx,[esp+8];i_h or ecx,31 cmp [esp+8],ecx rcr eax,1 xor ecx,edx cmp ecx,32 rcl eax,3 ret 12
Ver. 2.0 loindex = dword ptr [esp+4], hiindex = ...+8 Код (Text): loindex = dword ptr [esp+4], hiindex = ...+8, array = ...+0Ch xor eax, eax cdq mov ebp, array mov ebx, hiindex lea ebx, [ebx+ebp*8] bts eax, ebx mov ecx, loindex lea ecx, [ecx+ebp*8] xor ebx, ecx cmp ebx, 32 rcl eax, 1 adc eax, eax inc edx inc ecx ror edx, cl adc eax, eax
_BC_ Спасибо за варианты, но ты б обратил внимание на мой пост, пожалуйста. Нельзя игнорировать указатель. Указатель то в байтах, значит биты выравнены по восьми, а требуется внимание к двойным словам, значение в указателе влияет на выравненность по словам, одних индексов недостаточно. Гиганты в главном правы, а валятся на мелочах. Пожалуйста, повнимательней к мелочам. They matter.
Код (Text): ; eax = ptr to data ; ecx = lower index ; edx = higher indeh 8D0CC1 lea ecx, [ecx+eax*8] 8D14C2 lea edx, [edx+eax*8] 8BC1 mov eax, ecx 33C2 xor eax, edx C1E8 05 shr eax, 5 0F94C0 sete al 83CA E0 or edx, -20h 83C2 01 add edx, 1 10C0 adc al, al 83E1 1F and ecx, 1Fh 83E9 01 sub ecx, 1 10C0 adc al, al 34 03 xor al, 3 0FB6C0 movzx eax, al ЗЫ: долго думал, но так и не понял, правильно ли работает код %)
The Svin Если я правильно понял смысл задания, то для него достаточно "булевого" ответа, зачем махинации с тремя битами? mov eax,memory mov ecx,eax add eax,l_index add ecx,h_index or eax,ecx and eax,3 jz переход если диапазон выровнен по двойному слову (кратен 32-м битам)
Неа. Должен получится индекс "кейса". Один из восьми возможных. 000 оба выравнены и не принадлежат одному двойному слову 100 оба выравнены но принадлежат одному двойному слову и т.д. Воображаемому обработчику нужно знать, какие биты выравнены какие не выравнены и принадлежат ли они двойному слову.
Тогда нужен ещё бит, у нас есть бит для , а для старшего индекса нет? Или достаточно знать выравнены ли оба бита (весь диапазон)?
Так в условиях задачи и есть - установить состояние трёх бит. Нулевой, первый и второй. Пожалуйста, прочитай ещё раз условия в первом посте. Нулевой бит - состояние невыравнености младшего индекса Первый бит - старшего (является ли старшим дворда тут нельзя сказать выравненость, просто имеется есть ли в этом дворде после него ещё что-то) Второй бит - принадлежность обоих одному.
Я просто подумал, что второй бит проверка является ли старший индекс - старшим, т.е: 401004 ; memory = 401000 l_index = 4 401008 ; memory = 401000 h_index = 8 Здесь 0 (старший больше младшего) 401008 ; memory = 401000 l_index = 8 401004 ; memory = 401000 h_index = 4 Здесь 1 (старший меньше младшего, диапазон неверен) А третий бит проверяет, не оба ли индекса в одном дворде 401004 ; memory = 401000 l_index = 4 401005 ; memory = 401000 h_index = 5 Здесь оба в одном дворде, (втором от memory) По-этому был не ясен смысл первого бита, если он проверяет только младший бит, при таком условии у меня получилась огромная фигня Код (Text): mov eax,memory+l_index mov ecx,memory+h_index mov ebx,ecx cmp eax,ecx sbb edx,edx and ecx,edx xor edx,-1 and edx,eax or edx,ecx ; edx = max index sub ebx,eax sbb ecx,ecx and ecx,ebx xor ebx,ecx cmp ebx,1 sbb ebx,ebx and ebx,2 ; установить 2 бит в ebx если h_index < l_index add eax,ecx ; eax = min index sub edx,eax cmp edx,4 sbb ecx,ecx and ecx,4 ; установить 3 бит в ecx если memory+l_index & memory+h_index в одном дворде and eax,3 setnz al ; установить 1 бит в eax если memory+l_index не выровнен на 4 xor eax,ebx ; копировать 2 бит в eax xor eax,ecx ; копировать 3 бит в eax
_BC_ > Разве не видно, что код прямо из Olly? Он работает, но правильно ли я понял условие задачи - это и есть вопрос . И хорошо было бы не ограничиться , а привести пример входных данных дающий ошибочный результат. Вот, например, мои результаты: Код (Text): prt = 0, lo = 0, hi = 31, result = 4 = 100b // 7 ptr = 2, lo = 16, hi = 47, result = 4 = 100b // 7 ptr = 1, lo = 10, hi = 23, result = 5 = 101b // 6 ptr = 3, lo = 8, hi = 40, result = 2 = 010b // 9 ptr = 3, lo = 280, hi = 311, result = 4 = 100b // 9 В последней колонке приведены ответы твоего кода. Как видно, они отличаются от моих. Но я склоняюсь к тому, что верные именно мои, тк у тебя почему-то 3й бит = 1 Лично меня смущает необходимость последнего xor в моём коде. очевидно, что The Svin уже имеет решение, и поскольку результат используется для табличного перехода, не важно, чему конкретно равны биты (0 или 1). Значит арифметика у меня какая-то не та Единственное сравнение (условную установку байта) я оставил - при чистой арифметике на 3 байта больше получается.
Что то непонятно что это memory+h_index. Указатель он в байтах а индекс относительно него в битах. Ребята, я никак слов не могу подобрать, всё намекаю, намекаю Фиговый я намекальщик ) Ну почему сразу отвергать анализ, что может изменится при прибавлении указателя, какие биты могут, какие нет. как это повлиять может. Вы как-то изначально предмет байты+биты в сторону откинули и с головой ушли в поиски машинной команд покороче, и никак мне внимание не удаётся привлечь. Ну вспомните segment+offset и тучку других вещей с накладыванием чисел друг на друга. Задачка не обязательно должна быть решена минимально с точки размера, вообще индексные переводы делаются чаще для того чтобы побыстрее выполнить управление. Предположите к примеру (просчитайте) какие входящие вероятней и попытайтесь от входных данных построить наибыстрейшую модель при средне-ожидаемом входе.
Не лучше так к этому не относится ) Нет решений пока не показали. Можно вообще предположить что я эксплуатирую бесплатные мозги, чтобы они делали для меня домашнюю работу, а сам загребаю по 30000 евро per month с какой-нить зарубежной компани. С другой стороны даже в этом случае будет польза - потренироваться и проверить себя на задачках за которые платят 30000 евро per month.
Бл%$# !!! Я невнимательно прочитал условие. Я сделал 1 в ответе, если выравнен, 0 если наоборот. Но это элементарно правится ценой 2х байтов. Про цифру 9 в моих результатах -- это нормально. Ты просто не цифру бери, а три младших бита. В условии не сказано про судьбу битов 31-3 ответа. Главное, что биты 2-0 содержат то что надо. Да, и в последней строке... там 000b, а не 9. Не знаю как ты 9 (1) там получил. Я прогнал у себя с 3/280/311 и получил 000b (на не исправленном). Тогда вот так: ; ebp = base, ecx = low index, ebx = high index Код (Text): xor eax, eax cdq lea ebx, [ebx+ebp*8] bts eax, ebx lea ecx, [ecx+ebp*8] xor ebx, ecx cmp ebx, 32 rcl eax, 1 adc eax, eax inc edx inc ecx ror edx, cl adc eax, eax xor al, 011b Можно даже лучше сделать. Хотя и так мой код пока самый маленький.
The Svin Я твой намёк еще во втором своём сообщении учёл, только код там был не правильный, вот теперь правильный вариант: Код (Text): it_2:;(array +4, index_low +8, index_high +12) mov ecx,[esp+8] mov edx,[esp+12] mov eax,ecx mov ebx,edx shr eax,3; sar eax,3 правильному варианту потребовались исправления ;) shr ebx,3; sar ebx,3 но теперь должно работать add eax,[esp+4];адрес байта с младшим битом add ebx,[esp+4];адрес байта со старшим битом and ecx,7;номер младшего бита в байте and edx,7;номер старшего бита в байте lea ecx,[ecx+eax*8] lea edx,[edx+ebx*8] and eax,-4;адрес младшего двойного слова and ebx,-4;адрес старшего двойного слова and ecx,31;номер младшего бита в двойном слове and edx,31;номер старшего бита в двойном слове cmp eax,ebx setz al cmp edx,31 rcl eax,1 cmp ecx,1 cmc rcl eax,1 ret 12 All А что ваш код говорит при base=XXXXXXX1h Код (Text): index_low index_high 7FFFFFD8h,7FFFFFF7h ; 4 7FFFFFF8h,80000017h ; [b]0[/b] у вас здесь получился? [added]ноль должен быть не здесь[/added] 80000018h,80000037h ; 4 [added] а здесь: base=2,index_low=0FFFFFFF0h,index_high=00000000Fh [/added]