Есть переменная, которая содержит 16-ричное значение записанное в виде ASCII строки. Задача - перевести это строчное ASCII значение в 16ричный вид Код (Text): char asciiHexVal = "14ABEF"; На выходе надо получить Код (Text): int hexValue = 14ABEF;
думаю что посимвольно в цикле байт - 2 символа следовательно двойное слово 8 символов алгос примерно такой вычисляем длину строки идем от младшего с старшему, результат в начале инициализирован нулями в цикле берем символ, проверяем, конвертируем записываем +проверки на длину строки если больше 8 отбрасываем старшие разряды или генерим ошибку если меньше не трогаем старшие нули
Код (Text): ; by Alexander Yackubtchik htodw proc String:DWORD ; ----------------------------------- ; Convert hex string into dword value ; Return value in eax ; ----------------------------------- push ebx push esi push edi mov edi, String mov esi, String ALIGN 4 again: mov al,[edi] inc edi or al,al jnz again sub esi,edi xor ebx,ebx add edi,esi xor edx,edx not esi ;esi = lenth .while esi != 0 mov al, [edi] cmp al,'A' jb figure sub al,'a'-10 adc dl,0 shl dl,5 ;if cf set we get it bl 20h else - 0 add al,dl jmp next figure: sub al,'0' next: lea ecx,[esi-1] and eax, 0Fh shl ecx,2 ;mul ecx by log 16(2) shl eax,cl ;eax * 2^ecx add ebx, eax inc edi dec esi .endw mov eax,ebx pop edi pop esi pop ebx ret htodw endp
char c, *pstr, *str = "14ABEF"; int i; for(pstr = str, i = 0; *pstr; pstr++){ c = *pstr; i *= 16; if(c >= '0' && c <= '9') i += c - '0'; else if(c >= 'A' && c <= 'F') i += c - 'A'; else break; } int hexValue = i;
qqwe мой первый вариант решения этой странной задачи был Код (Text): for (int i=0; i<strlen(val); ++i) { ch = val[i]; Break; // 0..9 if ( ch >= '0' && ch <= '9' ) { ch = ch - '0'; // 0x30 indexes[i] = ch; continue; } // A..F (41..46) if ( ch >= 'A' && ch <= 'F' ) { ch = ch - 'A' + 10; indexes[i] = ch; } } for (int y=0; y<5; y++) { std::cout << indexes[y] << endl; } getch(); Но я подумал, что есть готовое решение
Все кажись разобрался: Код (Text): __declspec( naked ) void htodw(char *pData) { __asm{ push ebp mov ebp, esp push ebx push esi push edi mov edi, dword ptr ss:[ebp+8] mov esi, dword ptr ss:[ebp+8] nop __1: mov al, byte ptr ds:[edi] inc edi or al, al jnz __1 sub esi, edi xor ebx, ebx add edi, esi xor edx, edx not esi jmp __End __2: mov al, byte ptr ds:[edi] cmp al, 041h jb __3 sub al, 057h adc dl, 0 shl dl, 5 add al, dl jmp __4 __3: sub al, 030h __4: lea ecx, dword ptr ds:[esi-1] and eax, 0Fh shl ecx, 2 shl eax, cl add ebx, eax inc edi dec esi __End: or esi, esi jnz __2 mov eax, ebx pop edi pop esi pop ebx leave mov res, eax retn } } int main(int argc, char* argv[]) { __asm int 3 htodw("14ABEF"); printf("%X", res); return 0; }
Интересно, а как ты это скомпилешь в натив х64?) Мой совет - то что можно сделать на пуре Си лучше на нём и делать, выходной код всё равно по скорости будет такой же как и на чистом асме если не быстрее за счёт оптимизаций компилера.
KeSqueer принимается. задача такого рода, что даже не перечитывал JCronuz на х86 асме можно раза в 2 короче. можно даже операторов в 7.
d2k9 или в уникод? такой сурьезный алгос можно и под каждый проц переписывать. вопрос только - зачем его вообще на асме писать, если только вся прога не на асме?
Это велосипед, однако! http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/ Вопрос только: можно ли сделать быстрее на ассемблере, если надо.
AsmGuru62 а зачем? кроме того, работа с памятью перекроет почти любой оверхед в алгосе или реализации. и ее особо не ускоришь ну да, но может челу это не для С надо?
AsmGuru62 Мне нельзя использовать scanf, так как консоль используется мной только для вывода результата, а алгоритм нужен был для другого. Asterix Искал подобные темы, нашлось 3 листа из которых пролистал один да и забил. А тема очень полезная для меня спасибо.