Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler: Windows/protected mode
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.84/19: Рейтинг темы: голосов - 19, средняя оценка - 4.84
ut2010
1 / 1 / 1
Регистрация: 24.06.2012
Сообщений: 18
#1

Вывести 16-ричное число в консоль преобразовав в 10-ое число

06.01.2013, 00:56. Просмотров 3506. Ответов 42
Метки нет (Все метки)

В переменной esi хранится 16-е число 0000001h.
При выводе в консоль хочу получить соответственно 10-е число 1, а получаю "рожицу" (первый символ таблицы ASCII), а нужен 31 символ
Использую masm32.
Тему "Ввод и вывод чисел в различных системах счисления" читал, но там не то и под TASM.

Assembler
1
2
3
4
5
mov InNum, esi
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov outHandle, eax
PrintHex InNum
INVOKE WriteConsole, outHandle, offset InNum, InNumSize, offset bytesWritten, 0

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.01.2013, 00:56
Ответы с готовыми решениями:

Целое число перевести в 16-ричное и 8-ричное представление с помощью объекта
написать программу которая для введенного пользователя целого числа выводит...

Число uint разбить на 8 элементов по 4 бита, преобразовать каждый элемент в 16-ричное число
Не могу решить следующую задачу: Есть некоторое число uint (32-bit), его...

5-ричное число преобразовать в двоичное число
5-ричное число, введённое пользователем программы, преобразовать в двоичное...

Дано целое число. Вывести его строку-описание вида «отрицательное чет-ное число», «нулевое число», «положительное нечетное число» и т. д.
Дано целое число. Вывести его строку-описание вида «отрицательное чет-ное...

Как передать 16-ричное число в com-порт?
привет всем! торможу... как передать 16-ричное число в com-порт? нужно...

42
ValeryS
Модератор
7169 / 5436 / 674
Регистрация: 14.02.2011
Сообщений: 18,358
06.01.2013, 01:09 #2
Цитата Сообщение от ut2010 Посмотреть сообщение
При выводе в консоль хочу получить соответственно 10-е число 1, а получаю "рожицу" (первый символ таблицы ASCII), а нужен 31 символ
30h добавь к числу
код символа 0

Добавлено через 1 минуту
Цитата Сообщение от ut2010 Посмотреть сообщение
mov InNum, esi
add esi,30h
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 01:20 #3
ValeryS, для читабельности можно написать
Assembler
1
add esi, '0'
0
ValeryS
06.01.2013, 02:34
  #4

Не по теме:

Цитата Сообщение от Psilon Посмотреть сообщение
для читабельности можно написать
можно наверно :scratch:
просто для меня шеснадцетеричка как то ближе

0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 09:34 #5
ValeryS, ну лично я всю аски-таблицу наизусть не знаю. Пара эксекейп-символов, некоторые последовательности. Мне лично гораздо удобнее например для перевода из шестнадцатеричной писать а-дя
C
1
2
3
4
char ToHex(uint c)
{
   return c <=9 ? c + '0' : c + 'A';
}
чем вспоминать коды '0' и 'A'
0
taras atavin
4204 / 1764 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
06.01.2013, 09:38 #6
Цитата Сообщение от ut2010 Посмотреть сообщение
В переменной esi хранится 16-е число 0000001h.
Во-первых научись отличать память от регистров, во вторых в регистре на букву e не может быть шестнадцатеричного числа такой разрядности, а только двоичное, закодировать же цифрами в нём можно максимум четырёхзначное, а в-третьих откуда вообще взялось семизначное число?
0
ut2010
1 / 1 / 1
Регистрация: 24.06.2012
Сообщений: 18
06.01.2013, 19:10  [ТС] #7
Цитата Сообщение от taras atavin Посмотреть сообщение
Во-первых научись отличать память от регистров
Регистры ESI и EDI обычно используют для команд высокоскоростной пересылки данных из одного участка памяти в другой. И так в любой литературе.
Если вы о том, что не стоит использовать их для вычислений как регистры eax…, то я в данной программе использую регистр esi по назначению.
Это фрагмент программы, вычисляющей позицию подстроки в строке.
В esi сохраняю адрес смещения в строке S, а в случае совпадения подстроки – разницу смещения и начального адреса строки S
sub esi, offset S
Затем переношу данные в переменную InNum и работаю с ней.
Цитата Сообщение от taras atavin Посмотреть сообщение
во вторых в регистре на букву e не может быть шестнадцатеричного числа такой разрядности, а только двоичное
Да. Разобрался – там двоичное число:
PrintDec InNum дает 1
PrintHex InNum дает 00000001
Цитата Сообщение от taras atavin Посмотреть сообщение
а в-третьих откуда вообще взялось семизначное число?
Правильно так – 00000001h (семь нолей+единица), опечатка вышла.
Цитата Сообщение от ValeryS Посмотреть сообщение
30h добавь к числу
код символа 0

Добавлено через 1 минуту

add esi,30h
Попробовал так сделать, но это, пожалуй, не совсем правильно и работает только до цифры 9, затем в таблице идут знаки, буквы. А значения в esi будут и больше 9.

Мне нужно в консоль вывести то значение, которое дает в дебагере команда PrintDec InNum, собственно преобразованное в десятичное число, значение, хранящееся в InNum.
0
ValeryS
Модератор
7169 / 5436 / 674
Регистрация: 14.02.2011
Сообщений: 18,358
06.01.2013, 19:15 #8
Цитата Сообщение от ut2010 Посмотреть сообщение
А значения в esi будут и больше 9.
Цитата Сообщение от ut2010 Посмотреть сообщение
В esi сохраняю адрес смещения в строке S,
так что у тебя в esi? смещение или число которое надо вывести
Цитата Сообщение от ut2010 Посмотреть сообщение
Регистры ESI и EDI обычно используют для команд высокоскоростной пересылки данных из одного участка памяти в другой.
а могут и для другого
самое главное различие регистры внутри процессора, память снаружи
0
ut2010
1 / 1 / 1
Регистрация: 24.06.2012
Сообщений: 18
06.01.2013, 19:30  [ТС] #9
Если конкретно в esi число от 1 до 256, которое я сохраняю в переменной InNum, и уже значение InNum вывожу в консоль.
Не хотел выкладывать код до того как доделаю, но вот:
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
.386
.model flat, stdcall
option casemap: none
 
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\debug.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\debug.lib
 
.data
InNum dword ?
InNumSize = ($-InNum)
 
BufSize = 100h              
S Byte BufSize DUP(?)   
P Byte BufSize DUP(?)
InHandle DWORD ?            
bytesRead DWORD ?
 
Text byte "Press any key to continue"
TextSize = ($-Text) 
TheEnd byte "Nothing find"
TheEndSize = ($-TheEnd) ; длина сообщения в байтах
outHandle DWORD 0       ; дескриптор стандартного устройства вывода
bytesWritten  DWORD ?
 
.code
start:
 
INVOKE GetStdHandle, STD_INPUT_HANDLE 
mov InHandle,eax            
INVOKE ReadConsole, InHandle, offset S, BufSize, offset bytesRead, 0
INVOKE ReadConsole, InHandle, offset P, BufSize, offset bytesRead, 0
 
lea esi, S
lea edi, P
DbgDump esi, 4
DbgDump edi, 4
 
M1:
mov ecx, 4; LENGTHOF P-1
;PrintDec ecx, "LENGTHOF P-1"
 
push esi
push edi
cld
repe cmpsb
jne L1  ; не равно нулю
clc     ; CF=0 иначе равны
jmp L2
L1: stc ; CF=1 не равны
L2:     
    pop edi     
    pop esi
 
jc M2   ; если не равны
push esi
sub esi, offset S
inc esi
 
mov InNum, esi
DbgDump offset InNum, 4
;add InNum, 30h
 
INVOKE GetStdHandle, STD_OUTPUT_HANDLE ; дескриптор для вывода
mov outHandle, eax
PrintHex InNum, "PrintHex"
PrintDec InNum, "PrintDec"
INVOKE WriteConsole, outHandle, offset InNum, InNumSize, offset bytesWritten, 0
 
PrintHex InNum
pop esi
jmp M2
;ret
M2:
    inc esi
    cmp byte ptr [esi], 0
    jne M1
    ;mov InNum, 0
    ;Вывести ничего не найдено
    ;PrintDec InNum
 
    INVOKE GetStdHandle, STD_OUTPUT_HANDLE ; дескриптор для вывода
    mov outHandle, eax
    INVOKE WriteConsole, outHandle, offset TheEnd, TheEndSize, offset bytesWritten, 0
 
    INVOKE GetStdHandle, STD_INPUT_HANDLE 
    mov InHandle,eax    
    INVOKE ReadConsole, InHandle, offset P, BufSize, offset bytesRead, 0
    ret
    
end start

в 64 строке присваиваю
в 72 вывожу в консоль
P.S.: если будете запускать - первое слово любой длины, второе пока что обязательно 4 символа.
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 20:35 #10
Assembler
1
2
3
4
5
6
7
8
9
        cmp   esi, 10
        jl    ldigit
        add esi, 'A'
        sub esi, 10
        jmp lend
ldigit:  
        add esi, '0'
lend:
        ...
0
ut2010
1 / 1 / 1
Регистрация: 24.06.2012
Сообщений: 18
06.01.2013, 22:12  [ТС] #11
Цитата Сообщение от Psilon Посмотреть сообщение
Assembler
1
2
3
4
5
6
7
8
9
        cmp   esi, 10
        jl    ldigit
        add esi, 'A'
        sub esi, 10
        jmp lend
ldigit:  
        add esi, '0'
lend:
        ...
Ну так тоже не работает, да до 9 норм, а если больше, то идут буквы.
Сейчас пробую этот вариант дальше развить, но пока ничего хорошего не получается...
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 22:43 #12
ut2010, ну да, дальше буквы идут. Так и задумано ))
0
ValeryS
Модератор
7169 / 5436 / 674
Регистрация: 14.02.2011
Сообщений: 18,358
06.01.2013, 23:02 #13
Цитата Сообщение от Psilon Посмотреть сообщение
ut2010, ну да, дальше буквы идут. Так и задумано ))
тему то посмотри
Цитата Сообщение от ut2010 Посмотреть сообщение
преобразовав в 10-ое число
то есть тут нужен тупой остаток от деления на 10
что то типа
Assembler
1
2
3
4
5
6
7
8
9
10
metka:
or eax,eax
jz exit
mov ebx,10
div eax,ebx
add edx,'0'; здесь остаток от деления добавляем смещение 
тут как то выводим edx
jmp metka
 
exit:
или если выводимое значение не превышает 255 конвертировать в двоично-десятичный код
по моему есть такая команда у процессора
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 23:09 #14
ValeryS, ну лично я конвертировал сам.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
to_bcd macro x
    mov SavedAX, ax 
    mov SavedCX, cx
    ;сохранили исходные значения регистров
    mov ax, x   ; сохранили число в регистр ax
    mov bx, 2   ; основание системы BCD
    mov cx, 4   ; разбиваем на группы по 4 символа (BCD)    
bcd:        
    xor dx, dx
    div bx
    push dx 
    loop bcd
    ;восстановили исходные значения регистров 
    mov ax, SavedAX
    mov cx, SavedCX
    add cx, 4
endm
 
...
 
oi2:
    mov     bx, 10      ; основание сс. 10 для десятеричной и т.п.
    xor     dx,dx
    div     bx  
    to_BCD  dx
    test    ax, ax
    jz ex
    push    del     ; после тетрады выводим значок минуса
    inc     cx
    jmp     oi2
                ; Теперь приступим к выводу.
ex:    mov     ah, 02h
Добавлено через 1 минуту
В ax - число для перевода
0
ValeryS
Модератор
7169 / 5436 / 674
Регистрация: 14.02.2011
Сообщений: 18,358
06.01.2013, 23:22 #15
Цитата Сообщение от Psilon Посмотреть сообщение
xor * * dx,dx
слушай а я в своем решении забыл про обнуление
Цитата Сообщение от Psilon Посмотреть сообщение
ValeryS, ну лично я конвертировал сам.
извини не понял что конвертировал? в двоично десятичный?

Добавлено через 3 минуты
Цитата Сообщение от Psilon Посмотреть сообщение
mov bx, 2 * ; основание системы BCD
Цитата Сообщение от Psilon Посмотреть сообщение
div bx
деление очень долгая операция здесь лучше смешение вправо через перенос
а потом adc dx,0
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 23:55 #16
ValeryS, ну да, смещение быстрее) Только там остаток пропадает. А мне нужен именно остаток. Это самый быстрый способ получить этот остаток.
0
ValeryS
Модератор
7169 / 5436 / 674
Регистрация: 14.02.2011
Сообщений: 18,358
06.01.2013, 23:56 #17
вот нашел
побочное действие AAM
http://www.kolasc.net.ru/cdo/programmes/assembler/aam.html

AAM корректирует результат умножения двух неупакованных BCD, находящийся в AL. Данная команда просто делит содержимое AL на 10 и помещает частное в AH, а остаток — в AL. Таким образом в AX помещается двухразрядное неупакованное BCD. Стандартная версия команды не имеет операндов, однако существует расширенная версия AAM, в которой в роли операнда выступает непосредственное значение — база, на которую будет производиться деление. Так что, выполнив, к примеру, команду AAM 5, вы поделите нацело содержимое AL, получив частное в AH, а остаток — в AL. Очень удобный способ для деления нацело небольших (до 8 бит) чисел.
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 23:56 #18
Дело в том, что мои знания ассемблера ограничиваются двухчасовым курением методы и написанием лабораторки для подруги, из-за которой собственно и взялся за это дело. Так что знаю мало чего.
0
ut2010
1 / 1 / 1
Регистрация: 24.06.2012
Сообщений: 18
06.01.2013, 23:58  [ТС] #19
Ну всё. Всем спасибо.
Интересно получилось. Сам ушел решение додумывать, сделал через деление, с получением остатка. Кстати тоже, пропустил обнуление, но быстро исправился и вуаля ГОТОВО.
Истина была так близко.
Обновляю страничку, и вы предлагаете такой же вариант. Тема раскрыта.

Не по теме:

Код
На форуме есть ветка с готовыми решениями, куда можно скинуть решенную задачу? (в моем случае поиск подстроки в строке)

0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 23:59 #20
ut2010, ну можете в свой форумный блог запостить, а сюда ссылочку оставить.
0
06.01.2013, 23:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.01.2013, 23:59

найти двух байтное 16-ричное число используя цифры от 0 по F
var a:integer; begin a:=5; asm dw $9090 end; writeln (a); readln; end. ...

Дано целое число. Вывести его строку-описание вида «отрицательное четное число», «нулевое число »,« положительное нечетн
Дано целое число. Вывести его строку-описание вида «отрицательное четное...

Найти в файле data.txt максимальное число и вывести в консоль
в текстовом файле data.txt записано произвольное количество вещественных чисел...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru