Подскажите пожалуйста как преобразовать число в строку. т.е. нпример число 1 в строку "1"? С помощью какой функции? Заранее спасибо.
В книге П. И. Рудаков, К. Г. Финогенов ЯЗЫК АССЕМБЛЕРА: УРОКИ ПРОГРАММИРОВАНИЯ в Статья 13. Преобразование чисел в символьную форму есть алгоритм
Код (Text): Procedure_UBIN2STRDEC: push ebp mov ebp,esp push eax push edi mov eax,[ebp+8] mov edi,[ebp+12] push edx push ebx test eax,eax jnz @f mov ax,"0" stosw jmp Procedure_BIN2STRDEC_ZERO @@: cmp eax,1000000000 jnc Procedure_UBIN2STRDEC1000000000 cmp eax,100000000 jnc Procedure_UBIN2STRDEC100000000 cmp eax,10000000 jnc Procedure_UBIN2STRDEC10000000 cmp eax,1000000 jnc Procedure_UBIN2STRDEC1000000 cmp eax,100000 jnc Procedure_UBIN2STRDEC100000 cmp eax,10000 jnc Procedure_UBIN2STRDEC10000 cmp eax,1000 jnc Procedure_UBIN2STRDEC1000 cmp eax,100 jnc Procedure_UBIN2STRDEC100 cmp eax,10 jnc Procedure_UBIN2STRDEC10 jmp Procedure_UBIN2STRDEC1 Procedure_UBIN2STRDEC1000000000: xor edx,edx mov ebx,1000000000 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC100000000: xor edx,edx mov ebx,100000000 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC10000000: xor edx,edx mov ebx,10000000 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC1000000: xor edx,edx mov ebx,1000000 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC100000: xor edx,edx mov ebx,100000 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC10000: xor edx,edx mov ebx,10000 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC1000: xor edx,edx mov ebx,1000 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC100: xor edx,edx mov ebx,100 div ebx add al,0x30 stosb mov eax,edx Procedure_UBIN2STRDEC10: xor edx,edx mov ebx,10 div ebx add al,0x30 stosb mov al,dl Procedure_UBIN2STRDEC1: add al,0x30 stosb mov al,0 stosb Procedure_BIN2STRDEC_ZERO: pop ebx pop edx pop edi pop eax pop ebp ret
rudik Можно проще, например перевожу 64-битное число в строку (в edx старшая половина, в eax -- младшая) Код (Text): .data Data_Int64 dq ?;64-разрядное число Data_BCD dt ?;число в BCD-формате .code ... IntToStr proc or edx,edx ;число 64-разрядное? jnz b1 cmp eax,10 ;число меньше 10? jae b0 add al,30h stosb ret b0: cmp eax,100 ;число меньше 100? jae b1 aam add ax,3030h xchg ah,al stosw ret b1: push ecx mov dword ptr Data_Int64,eax;младшая часть 64-разрядного числа mov dword ptr Data_Int64+4,edx;старшая часть 64-разрядного числа fninit ;сброс сопроцессора fild Data_Int64 ;загрузить число в двоичном коде fbstp Data_BCD ;извлечь число в коде BCD mov ecx,9 ;в десятом байте информация о знаке числа b2: cmp byte ptr [ecx-1+Data_BCD],0 jnz b3 loop b2 ;пропускаем незначащие (нулевые) разряды слева b3: mov al,byte ptr [ecx-1+Data_BCD];загружаем первую значащую пару разрядов cmp al,9 ;если в старшей тетраде 0 - пропустить старшую тетраду ja b4 add al,30h ;младшую тетраду переводим в ASCII stosb dec ecx b4: mov ah,byte ptr [ecx-1+Data_BCD];распаковываем остальные разряды числа shr ax,4 ;выделяем старшую и младшую тетрады shr al,4 add ax,3030h ;переводим в ASCII-код xchg ah,al stosw loop b4 pop ecx ret IntToStr endp
n0name Можно использовать OR, AND, TEST, SUB REG,0, XOR REG,0 ADD REG,0 -- чтобы узнать есть ли нуль в регистре. Цели оптимизировать по скорости не было, скорее -- получение компактного кода. Но я думаю что три операции fninit/fild/fbstp выполнятся быстрее чем деление в цикле на 10 в результате преобразования 64-битного числа в строку, хотя деление можно заменить умножением на "Magic Number"
Нашел еще одну интересную реализацию Код (Text): mov ebx,10 mov edi,offset Строка mov eax,Число mov esi,esp sub esp,16 xor ecx,ecx a1: dec esi xor edx,edx div ebx add dl,"0" mov [esi],dl inc ecx test eax,eax jnz a1 rep movsb add esp,16
Код (Text): .text .globl main main: pushl $1234567890 pushl $fmode call printf popl %ebx popl %edx .data fmode: .ascii "%d\n"