Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вывод 2х,3х.4х значного числа на экран  (Прочитано 16412 раз)
0 Пользователей и 1 Гость смотрят эту тему.
FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« : 06-11-2007 17:46 » 

1. Программа выводящая 2-4 значные числа на экран
2. МАСМ611, АМД 1.7
3. Конвертирование числа в символьный массив происходит почленными делением, разбивая на разряды и занося их в новый массив,а затем обратным считыванием производится вывод
4.  А черт его знает... Попытался как смог закомментировать свои действия, но на экране мусор. Мб что то забыл, или не правильно использовал какую то команду. Программу попросил написать преподователь, поэтому исходный код работающей проги брать не стал-пишу сам.

Код:
SSEG SEGMENT STACK
  DB 256 DUP (?)
SSEG ENDS

DATA SEGMENT
  NEW_A DB 6 DUP (?)  ; Массив для записи результата по разрядам
  NUM DB 149          ; Число которое будем выводить на экран
DATA ENDS

CODE SEGMENT
  ASSUME CS:CODE,DS:DATA,SS:SSEG
  START PROC FAR
    PUSH DS
    PUSH AX
    MOV BX,DATA
    MOV DS,BX
    CALL MAIN
    RET
  START ENDP

  MAIN PROC FAR
    XOR AX,AX
    XOR BX,BX
    XOR CX,CX
    XOR DX,DX
 
    MOV CX,2 ;Цикл на 3 итерации
    MOV SI, OFFSET NEW_A          ;В регистр SI поместили адрес массива NEW_A
 
    MOV AL,NUM                    ;Занесли в делимое число, которое надо вывести на экран
    MOV DL,10                     ;Будем делить наше число на 10, тем самым разбивая на порядки
M:
   
    DIV DL         ;Делим. Остаток в AH, результат в AL (AH=9, AL=14)(AH=4, AL=1)
   
    MOV [SI],AH    ;Поместили первый остаток как первый элемент массива _ _ _ _ _ 9 , _ _ _ _ 4 9
    INC SI         ;Для записи выставлен следующий элемент

    CMP AL,00001010B     ;Сравниваем результат с десяткой
    JB FINISH_DIV  ;Если AL меньше десятки, то переход на завершение деления
                   ;и помещения частного последним элементом массива
       
LOOP M

FINISH_DIV :

    MOV [SI],AL ;Записывается последняя еденица в разряд сотни _ _ _ 1 4 9         

    MOV CX,3 ; Цикл на 3 итерации   
N:
    MOV DL,NEW_A[SI]  ;Текущий элемент массива помещается в DL
    OR DL,00110000B   ;Добавляется признак ASCII кода
    MOV AH,2          ;Для вывода через прерывание 21h
    INT 21H
    DEC SI            ;Для вывода выставлен предыдущий элемент (941 = 1->4->9)
LOOP N
   
    RET
  MAIN ENDP

CODE ENDS
END START
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 06-11-2007 19:26 » 

FallenSoul, пытаюсь разобраться (но уставшее я щас), пробую в VC++6 , вот тут мне компилятор ругается:
Код:
mov [SI],AH

говорит что illegal reference to 16-bit data in 'first operand' . И хочь ты тресни. А я не помню, почему тут так

и вообще, если не ошибаюсь , лучше вместо
Код:
MOV SI, OFFSET NEW_A
...
mov [SI],AH

сделать
Код:
MOV SI, 0
...
mov NEW_A[SI],AH
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 06-11-2007 19:33 » 

Леш, все потому, что в студии ты 32-битный код пишешь, а тут 16-битный - просто не совместимо.

FallenSoul, отладчиком пройди пошагово и посмотри, где результат не тот, что ожидался.
« Последнее редактирование: 06-11-2007 19:41 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 06-11-2007 19:37 » 

RXL, аа , блин, надо же esi  юзать ))) В студии то есть

Делится, кстати, правильно. Значит косяк в работе с прерыванием. Это я уже не проверю...
« Последнее редактирование: 06-11-2007 19:39 от Алексей1153++ » Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 06-11-2007 20:05 » 

на вскидку
а POP AH, POP DS?
 XOR CX,CX Лишнее, за ним  MOV CX,2

 MOV AH,2 можно вынести за пределы цикла N

кроме того в самой процедуре MAIN портятся регистры, кто их будет восстанавливать?
а так похоже на правду


Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 07-11-2007 11:50 » 

Вот пример функции которая отображает шестнадцатиразрядное число. Только используется не функция DOS (21h), а функция BIOS (10h). Если необходимо использовать именно сервисы DOS (например, чтобы работало перенаправление ввода-вывода) то замени вызов BIOS-а вызовом DOS.

Код:
/* ax - число для отображения в hex */
print_hex:
pushw %cx
pushw %dx

movw $4,%cx          /* 4 hex числа */
movw %ax,%dx         /* регистр AX будет нужен для вызова int */

1: rolw $4,%dx          /* получим старшие 4 разряда */
movw $0xe0f,%ax      /* ah = вызов BIOS, al = маска значения */
andb %dl,%al
daa                  /* преобразуем в ASCII hex (три инструкции) */
addb $0xf0,%al
adcb $0x40,%al       /* al = ASCII hex 0..9A..F */
int $0x10            /* отобразим с использованием BIOS */
loop 1b              /* повторим для четырех значений */

popw %dx
popw %cx
ret
Записан
FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 07-11-2007 13:13 » 

Спасибо, но я свою дописал Улыбаюсь

С помощью TD прошёлся по программе, подкорректировал некоторые моменты. Вот собственно результат.

Спасибо всем кто ответил!
Код:
SSEG SEGMENT STACK
  DB 256 DUP (?)
SSEG ENDS

DATA SEGMENT
  NEW_A DB 6 DUP (?)  ; Массив для записи результата по разрядам
  NUM DB 149          ; Число которое будем выводить на экран
DATA ENDS

CODE SEGMENT
  ASSUME CS:CODE,DS:DATA,SS:SSEG
  START PROC FAR
    PUSH DS
    PUSH AX
    MOV BX,DATA
    MOV DS,BX
    CALL MAIN
    RET
  START ENDP

  MAIN PROC
    XOR AX,AX
    XOR BX,BX
    XOR DX,DX
 
    MOV CX,2                      ;Цикл на 2 итерации (0-255. 255/100<10)
    MOV SI, OFFSET NEW_A          ;В регистр SI поместили адрес массива NEW_A
  
    MOV AL,NUM                    ;Занесли в делимое число, которое надо вывести на экран
    MOV DL,10                     ;Будем делить наше число на 10, тем самым разбивая на порядки
M:
  
    DIV DL         ;Делим. Остаток в AH, результат в AL (AH=9, AL=14)(AH=4, AL=1)
    
    MOV [SI],AH    ;Поместили первый остаток как первый элемент массива _ _ _ _ _ 9 , _ _ _ _ 4 9
    INC SI         ;Для записи выставлен следующий элемент

    CMP AL,00001010B     ;Сравниваем результат с десяткой
    JL FINISH_DIV        ;Если AL меньше десятки, то переход на завершение деления
                         ;и помещения частного последним элементом массива
    MOV AH,0
    MOV DL,10  
LOOP M

FINISH_DIV :

    MOV AH,2          ;Для вывода через прерывание 21h
    MOV [SI],AL ;Записывается последняя еденица в разряд сотни _ _ _ 1 4 9        

    MOV CX,3 ; Цикл на 3 итерации  
N:
    MOV DL,NEW_A[SI]  ;Текущий элемент массива помещается в DL
    OR DL,00110000B   ;Добавляется признак ASCII кода
    CMP DL,00110000B  ;Если не цифра, (<0)
    JL QUIT           ;то на выход
    CMP DL,00111010B  ;Если не цифра, (>9)
    JNL QUIT          ;то на выход
    INT 21H
    DEC SI            ;Для вывода выставлен предыдущий элемент (941 = 1->4->9)
LOOP N
  
QUIT:
    RET
  MAIN ENDP

CODE ENDS
END START
« Последнее редактирование: 07-11-2007 13:20 от FallenSoul » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines