День добрый! Вот понадобилось строку в число конвертировать, взял МАСМовскую atodw, немного изменил (убрал проверку на минус, мне это не понадобится, и переделал под UNICODE), и вот что получилось: Code (Text): StrToInt proc xor eax, eax xor ecx, ecx mov ax, [edx] add edx, 2 jmp L1 L0: sub ax, 30h lea ecx, [ecx+ecx*4] lea ecx, [eax+ecx*2] mov ax, [edx] add edx, 2 L1: test ax, ax jnz L0 lea eax, [ecx] retn StrToInt endp указатель на строку передаю в EDX. Всё чудесно, но радость несколько омрачается полным непониманием того, как она работает =( Знаю, что для конвертирования нужно из кода символа вычесть код символа 0 (30h) и умножить на 10 в степени <кол-во символов минус позиция>. Всё вроде прозрачно, но как всё эту работу делают две команды LEA? Тут вообще нигде не определятся количество символов, непонятно где тут счётчик позиции! Расскажите, пожалуйста, как всё это работет и посоветуйте умные книжки, где рассказано как можно овладеть таким кунг-фу =)
Code (Text): lea ecx, [ecx+ecx*4] ; ecx := ecx + 4*ecx т.е. ecx := 5*ecx lea ecx, [eax+ecx*2] ; ecx := eax + 2*ecx т.е. ecx := eax + 10*ecx Надеюсь, что я прав.
Да, действительно, разложил по кусочкам, посчитал всё на бумажке, и стало понятно! Непонятно только, как кто-то додумался до такой замечательной формулы =D MHajduk, crypto, спасибо!
MrBean Рекуррентность - чрезвычайно мощный инструмент, широко используемый в математике (ну и в программировании тоже, ес-но).
Непременно познакомлюсь с рекуррентностью, но чуть позже. У меня ещё вопрос по теме конвертирования строк и чисел. Вот уже самостоятельно набросал функцию перевода числа в строку: Code (Text): IntToStr proc mov ecx, 10 @@: cdq idiv ecx add edx, 30h mov [ebx], dx add ebx, 2 test eax, eax jnz @b mov [ebx], ax retn IntToStr endp число передаётся в EAX, указатель на буфер в EBX Пара вопросов по ней. Не обращая внимания на то, что число в строке отображается зеркально =D (это мы починим, я думаю, нет смысла двигать слова внутри цикла, лучше это сделать после, или есть способ лучше?), что можно в ней подправить? Что здесь уместнее cdq или xor edx, edx?
MrBean Вообще-то в данном случае неизвестно значение eax, поэтому cdq и xor edx, edx здесь не эквивалентны. Хотя... мож как всегда чушь несу.
l_inc ну вообще-то cdq здесь используеться не как эквивалент xor edx, edx... Code (Text): IDIV performs a signed division. The dividend, quotient, and remainder are implicitly allocated to fixed registers. Only the divisor is given as an explicit r/m operand. The type of the divisor determines which registers to use as follows: Size Divisor Quotient Remainder Dividend byte r/m8 AL AH AX word r/m16 AX DX DX:AX dword r/m32 EAX EDX EDX:EAX
nobodyzzz Я о том и говорю, что они не эквивалентны. И учитывая вопрос очевидно, что для знакового деления здесь xor edx, edx не подойдет, а для беззнакового cdq не подойдет. Я же просто написал, что они не эквивалентны, отвечая на вопрос.
Спасибо, учту все замечания. Знак меня действительно не интересует. Вот ещё немного кода. Попытка решить проблему зеркального отображения строки. Не функция, просто код "переварачивающий" число. Собираюсь вставить его в начало функции IntToStr. Code (Text): mov eax, 12345 mov ecx, 10 xor ebx, ebx @@: xor edx, edx div ecx lea ebx, [ebx+ebx*4] shl ebx, 1 add ebx, edx test eax, eax jnz @b ;в EBX 54321 какие здесь замечания? --- upd Это я же, просто случайно отписал с аккаунта брата. Он разлогиниться забыл, а я не заметил =)
Всё, полностью разобрался в вопросе, всё понял. Всем, принимавшим участие в обсуждении, огромное спасибо и респект! Вопросов больше не имею.
Yaroslav код shl ebx, 1/ add ebx, edx (D1E3 03DA - 4 байта) эквивалентен lea ebx,[ebx*2+edx] (8D1C5A - 3 байта)