Форум программистов, компьютерный форум, киберфорум
Наши страницы

Assembler: Windows/protected mode

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.84
ut2010
1 / 1 / 0
Регистрация: 24.06.2012
Сообщений: 18
#1

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

06.01.2013, 00:56. Просмотров 3452. Ответов 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-ричное число в консоль преобразовав в 10-ое число (Assembler):

Вывести на консоль сумму элементов первого массива, превышающих введённое число, и сумму элементов второго, не превышающих его - Assembler
Помогите решить лабораторные: 1,Задан символьный массив. Ввести с клавиатуры символ и вывести на консоль количество таких символов в...

Дана строка. Если скобки расставлены правильно, то вывести число 1. В противном случае вывести всю строку - Assembler
Дана строка, содержащая несколько круглых скобок. Если скобки расставлены правильно (то есть каждой открывающей соответствует одна...

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

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

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

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

42
ValeryS
Модератор
6963 / 5300 / 522
Регистрация: 14.02.2011
Сообщений: 17,876
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
5932 / 4831 / 636
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 01:20 #3
ValeryS, для читабельности можно написать
Assembler
1
add esi, '0'
0
ValeryS
06.01.2013, 02:34
  #4

Не по теме:

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

0
Psilon
Master of Orion
Эксперт .NET
5932 / 4831 / 636
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 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
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
06.01.2013, 09:38 #6
Цитата Сообщение от ut2010 Посмотреть сообщение
В переменной esi хранится 16-е число 0000001h.
Во-первых научись отличать память от регистров, во вторых в регистре на букву e не может быть шестнадцатеричного числа такой разрядности, а только двоичное, закодировать же цифрами в нём можно максимум четырёхзначное, а в-третьих откуда вообще взялось семизначное число?
0
ut2010
1 / 1 / 0
Регистрация: 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
Модератор
6963 / 5300 / 522
Регистрация: 14.02.2011
Сообщений: 17,876
06.01.2013, 19:15 #8
Цитата Сообщение от ut2010 Посмотреть сообщение
А значения в esi будут и больше 9.
Цитата Сообщение от ut2010 Посмотреть сообщение
В esi сохраняю адрес смещения в строке S,
так что у тебя в esi? смещение или число которое надо вывести
Цитата Сообщение от ut2010 Посмотреть сообщение
Регистры ESI и EDI обычно используют для команд высокоскоростной пересылки данных из одного участка памяти в другой.
а могут и для другого
самое главное различие регистры внутри процессора, память снаружи
0
ut2010
1 / 1 / 0
Регистрация: 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
5932 / 4831 / 636
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 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 / 0
Регистрация: 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
5932 / 4831 / 636
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 5
Завершенные тесты: 4
06.01.2013, 22:43 #12
ut2010, ну да, дальше буквы идут. Так и задумано ))
0
ValeryS
Модератор
6963 / 5300 / 522
Регистрация: 14.02.2011
Сообщений: 17,876
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
5932 / 4831 / 636
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 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
Модератор
6963 / 5300 / 522
Регистрация: 14.02.2011
Сообщений: 17,876
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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.01.2013, 23:22
Привет! Вот еще темы с ответами:

Как передать 16-ричное число в com-порт? - C++
привет всем! торможу... как передать 16-ричное число в com-порт? нужно передать 0x11 и 0x22 в com-порт, а порт принимает char*. вот...

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

Как разбить число на цифры и вывести в консоль без массивов? - C (СИ)
Подскажите алгоритм.

Найти в файле data.txt максимальное число и вывести в консоль - C#
в текстовом файле data.txt записано произвольное количество вещественных чисел через пробел. Написать программу, которая находит...


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

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

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