2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 ASM вывод числа на экран
Сообщение18.12.2012, 19:25 


17/12/12
6
Доброго времени суток!
Я не так давно начал изучать ассемблер и сейчас у меня возникла проблема с выводом чисел на экран.
Гуглил много, но ничего подходящего не нашел, лишь узнал что для вывода числа его сначала нужно преобразовать в строку. Так вот хотелось бы узнать каким образом можно некоторое число конвертировать в строчку и вывести. Если вы знаете, другие способы вывода числа на экран, то прошу написать, ибо это будет весьма полезно.

З.Ы. Использую TASM

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 19:39 
Аватара пользователя


20/10/12
308
Научитесь вызывать функции из libc , a дальше -- по старому.

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 20:20 


05/09/12
2587
Берем число (например, двухбайтовое целое), пока оно больше 10000 - вычитаем из него 10000, считаем сколько раз вычли в отдельном регистре. Прибавляем к значению регистра счетчика код символа "0" - получаем код символа нужной цифры текущего десятичного разряда - шлем его по USART на комп где в любой терминальной программе он выводится как десятичная цифра. Далее - в исходных регистрах у нас остался остаток меньше 10000 - начинаем вычитать из него 1000 и действуем по тому уже алгоритму.

(Оффтоп)

Код:
   
   .include "Tn13def.inc"

; функции ножек

   .equ   _PIN_PC_OUT            = PB2      ; 7 - й PIN - вывод данных на комп
   .equ   _PIN_RELE_OUT1         = PB3      ; 2 - й PIN - выход на обмотку 1
   .equ   _PIN_RELE_OUT2         = PB1      ; 6 - й PIN - выход на обмотку 2
   .equ   _PIN_RELE_IN1         = PB4      ; 3 - й PIN - вход контакта 1
   .equ   _PIN_RELE_IN2         = PB0      ; 5 - й PIN - вход контакта 2

; регистры общего назначения

   .def   _r_mom               = r16      ; служебный регистр для записи в порты
   .def   _r_WAIT               = r17

   .def   _r_count_measure_sets   = r18
   .def   _r_transmit_data      = r19

   .def   _r_t1_lb            = r20
   .def   _r_t1_hb            = r21
   .def   _r_t1_last_lb         = r22
   .def   _r_t1_last_hb         = r23
   .def   _r_t2_lb            = r24
   .def   _r_t2_hb            = r25
   .def   _r_t2_last_lb         = r26
   .def   _r_t2_last_hb         = r27

   .def   _r_count_measure_time_lb   = r28
   .def   _r_count_measure_time_hb   = r29

; переменные

   .equ   _one_measure_time      = 96      ; тактов = 10us - дискретность измерения

   .equ   _max_measure_time      = 3000      ; циклов по 10us = 30ms - интервал измерения

   .equ   _sets_of_measures      = 10      ; количество измерений (1 измерение = туда + обратно)

   ;.equ   _RS232_time            = 1000      ; тактов бита RS232 для скорости 9600 бод
   .equ   _RS232_time            = 250      ; тактов бита RS232 для скорости 38400 бод

; для десятичной системы исчисления

   .equ   _SI_order            = 10      ; для десятичной системы исчисления при выводе результатов
   ;.equ   _max_length_SI         = 5         ; макс. разрядность чисел в _SI_order

   .equ   _SI_order_0            = 1
   .equ   _SI_order_1            = _SI_order
   .equ   _SI_order_2            = _SI_order_1*_SI_order_1
   .equ   _SI_order_3            = _SI_order_2*_SI_order_1
   .equ   _SI_order_4            = _SI_order_3*_SI_order_1

; нужные коды KOI_8

   .equ   KOI_8_comma            = $2C      ; код ","
   .equ   KOI_8_semicolon         = $3B      ; код ";"
   .equ   KOI_8_ps            = $0A      ; код "перевод строки"
   .equ   KOI_8_vk            = $0D      ; код "возврат каретки"

;--------------------------------------------------------------------

   rjmp   RESET                      ; Reset Handler
   reti      ;rjmp EXT_INT0             ; IRQ0 Handler
   reti      ;rjmp   PIN_CHANGE                   ; PCINT0 Handler
   reti      ;rjmp TIM0_OVF             ; Timer0 Overflow Handler
   reti      ;rjmp EE_RDY             ; EEPROM Ready Handler
   reti      ;rjmp ANA_COMP             ; Analog Comparator Handler
   reti      ;rjmp   TIM0_COMPA                   ; Timer0 CompareA Handler
   reti      ;rjmp TIM0_COMPB          ; Timer0 CompareB Handler
   reti      ;rjmp WATCHDOG             ; Watchdog Interrupt Handler
   reti      ;rjmp ADCCONV            ; ADC Conversion Handler
;--------------------------------------------------------------------

RESET:

   ldi    _r_mom, (1<<_PIN_RELE_OUT1) + (1<<_PIN_RELE_OUT2) + (1<<_PIN_PC_OUT)
   out    DDRB, _r_mom            ; пины выходов

   ldi    _r_mom, (1<<_PIN_RELE_IN1) + (1<<_PIN_RELE_IN2)
   out    PORTB, _r_mom            ; подтягиваюие резисторы на входы

;   ldi    _r_mom, (1<<_PIN_RELE_IN1) + (1<<_PIN_RELE_IN2) + (1<<_PIN_RELE_OUT1) + (1<<_PIN_RELE_OUT2)
;   out    PCMSK, _r_mom            ; маска пинов для прерываний по pin change

   rjmp    MAIN
;--------------------------------------------------------------------
; прерывание по изменению состояния выводов

;PIN_CHANGE:

;   clr    _r_mom
;   out    GIMSK, _r_mom

;   reti
;--------------------------------------------------------------------

WAIT_Idle:

   ; для относительно длинных пауз
   ; ждем в состоянии Idle ПРИМЕРНО _r_WAIT / 37.5 секунд

   cli

;   clr    _r_mom
;   out    GIMSK, _r_mom

   in       _r_mom, MCUCR
   cbr    _r_mom, (1<<SM0) + (1<<SM1)
   sbr    _r_mom, (1<<SE)
   ;ldi    _r_mom, (0<<ISC00) + (0<<ISC01) + (0<<SM0) + (0<<SM1) + (1<<SE) + (0<<PUD)
   out    MCUCR, _r_mom      ; задаем режим sleep-а Idle и устанавливаем флаг его разрешения

   ldi    _r_mom, 250
   out    OCR0A, _r_mom      ; значение счетчика таймера для прерывания
   clr    _r_mom
   out    TCNT0, _r_mom      ; сброс счетчика таймера
   ldi    _r_mom, (1<<OCIE0A)
   out    TIMSK0, _r_mom      ; разрешаем прерывание по счетчику таймера
   ldi    _r_mom, (1<<CS02) + (0<<CS01) + (1<<CS00)
   out    TCCR0B, _r_mom      ; запускаем таймер с частотой СК/1024

   sei

   WAIT_Idle_sleep:

   sleep                  ; Idle

   clr    _r_mom
   out    TCNT0, _r_mom      ; сброс счетчика таймера

   dec    _r_WAIT
   brne    WAIT_Idle_sleep

   cli
   
   in       _r_mom, MCUCR
   cbr    _r_mom, (1<<SE)
   out    MCUCR, _r_mom      ; сбрасываем флаг разрешения sleep-а

   clr    _r_mom
   out    TIMSK0, _r_mom      ; запрещаем прерывание по счетчику таймера
   out    TCCR0B, _r_mom      ; останавливаем таймер
   out    OCR0A, _r_mom      ; нулевое значение счетчика таймера для прерывания
   out    TCNT0, _r_mom      ; сброс счетчика таймера

   ret
;;--------------------------------------------------------------------
;
;EEPROM_write:
;
;   sbic   EECR, EEPE
;   rjmp    EEPROM_write
;      
;   ; Set Programming mode
;   ldi    _r_mom, (0<<EEPM1)|(0<<EEPM0)
;   out    EECR, _r_mom
;
;   out    EEARL, _r_EEPROM_address
;   out    EEDR, _r_EEPROM_data
;   sbi    EECR, EEMPE
;   sbi    EECR, EEPE
;   ret
;;--------------------------------------------------------------------
;
;EEPROM_read:
;
;   sbic    EECR, EEPE
;   rjmp    EEPROM_read
;   out    EEARL, _r_EEPROM_address
;   sbi    EECR, EERE
;   in      _r_EEPROM_data, EEDR
;   ret
;;--------------------------------------------------------------------

DECIMAL_value_KOI_8:

   ; _r_t1_hb:_r_t1_lb - остаток от числа, _SI_order-ичный разряд которого надо получить
   ; _r_count_measure_time_hb:_r_count_measure_time_lb - число _SI_order в нужной степени
   ; результат - в _r_transmit_data (и уже +$30 к цифре для получения её кода KOI-8)

   clr      _r_transmit_data

   DECIMAL_value_KOI_8_1:

   cp      _r_t1_lb, _r_count_measure_time_lb
   cpc      _r_t1_hb, _r_count_measure_time_hb
   brlo   DECIMAL_value_KOI_8_END
   sub      _r_t1_lb, _r_count_measure_time_lb
   sbc      _r_t1_hb, _r_count_measure_time_hb
   inc      _r_transmit_data
   rjmp   DECIMAL_value_KOI_8_1

   DECIMAL_value_KOI_8_END:

   ldi      _r_mom, $30            ; свиг для кода KOI-8 цифры
   add      _r_transmit_data, _r_mom

   ret
;--------------------------------------------------------------------

PAUSE_RS232:

   ; _RS232_time - 13 (тактов на операции при передаче) - 5 (вызов rcall) - 2 (ret)
   ; итог / 5 (тактов каждого цикла) = в счетчик

   ldi    _r_mom, (_RS232_time - 13 - 5 - 2) / 5;

   PAUSE_RS232_Count:

   dec      _r_mom
   nop
   nop
   brne   PAUSE_RS232_Count

   ret
;--------------------------------------------------------------------

DATA_transmit_RS232:

   ; содержимое _r_transmit_data - на комп по RS232

   cli

   ; отправляем посылку RS232
   ; 13 тактов операций после каждого бита + (_RS232_time - 9) тактов паузы

   cbi      PORTB, _PIN_PC_OUT   ; старт-бит, до сего момента у нас была 1-ца и долго
   rcall   PAUSE_RS232
   nop
   nop
   nop
   nop
   nop
   nop

   ; 8 бит данных и 2 стоп бита = 10 бит
   ; для посылки их в одном цикле инвертируем байт даннных
   ; и будем посылать инвертированные биты - 2 стоп бита получатся
   ; как инвертированные нули при логическом сдвиге вправо :)

   com      _r_transmit_data
   ldi      _r_WAIT, 10

   DATA_transmit_RS232_DATA_BITS:

   sbrc   _r_transmit_data, 0
   cbi      PORTB, _PIN_PC_OUT
   sbrs   _r_transmit_data, 0
   sbi      PORTB, _PIN_PC_OUT

   rcall   PAUSE_RS232
   nop
   nop
   nop
   nop

   lsr      _r_transmit_data
   dec      _r_WAIT
   brne   DATA_transmit_RS232_DATA_BITS

   ; по хорошему, надо было запомнить флаг прерывания в начале процедуры
   ; и вернуть его такой же в конце. Но мы не будем возвращать
   ; - по умолчанию живем без прерываний, если надо - выставим когда надо
   ;sei

   ret
;--------------------------------------------------------------------

VALUE_transmit_RS232:

   ;_r_t1_hb:_r_t1_lb - на комп по RS232 в десятичной системе с запятой
   ;_r_count_measure_time_hb:_r_count_measure_time_lb - _SI_order
   ;_r_transmit_data - который потом шлем на комп по RS232

   ldi      _r_count_measure_time_lb, low(_SI_order_4)
   ldi      _r_count_measure_time_hb, high(_SI_order_4)
   rcall    DECIMAL_value_KOI_8
   rcall    DATA_transmit_RS232

   ldi      _r_count_measure_time_lb, low(_SI_order_3)
   ldi      _r_count_measure_time_hb, high(_SI_order_3)
   rcall    DECIMAL_value_KOI_8
   rcall    DATA_transmit_RS232

   ldi      _r_count_measure_time_lb, low(_SI_order_2)
   ldi      _r_count_measure_time_hb, high(_SI_order_2)
   rcall    DECIMAL_value_KOI_8
   rcall    DATA_transmit_RS232

   ; запятая
   ldi      _r_transmit_data, KOI_8_comma
   rcall    DATA_transmit_RS232

   ldi      _r_count_measure_time_lb, low(_SI_order_1)
   ldi      _r_count_measure_time_hb, high(_SI_order_1)
   rcall    DECIMAL_value_KOI_8
   rcall    DATA_transmit_RS232

   ldi      _r_count_measure_time_lb, low(_SI_order_0)
   ldi      _r_count_measure_time_hb, high(_SI_order_0)
   rcall    DECIMAL_value_KOI_8
   rcall    DATA_transmit_RS232

   ret
;--------------------------------------------------------------------

MEASURE_transmit_RS232:

   ; вынес в процедуру ИСКЛЮЧИТЕЛЬНО из-за ограничения количества строк перехода!

   ;_r_t1_hb:_r_t1_lb - на комп по RS232 в десятичной системе с запятой
   ;_r_count_measure_time_hb:_r_count_measure_time_lb - _SI_order
   ;_r_transmit_data - который потом шлем на комп по RS232

   ; сначала рассчитаем и приготовим все нужные рагистры для передачи
   ; а потом уже передадим - при передаче они корежатся :)

   ; расчет и запись ti_last как разница ti_lastт - ti

   cp      _r_t1_last_lb, _r_t1_lb
   cpc      _r_t1_last_hb, _r_t1_hb
   brlo   _clr_r_t1_last
   sub      _r_t1_last_lb, _r_t1_lb
   sbc      _r_t1_last_hb, _r_t1_hb
   rjmp   _calc_r_t1_last_end
_clr_r_t1_last:
   clr      _r_t1_last_lb
   clr      _r_t1_last_hb
_calc_r_t1_last_end:

   cp      _r_t2_last_lb, _r_t2_lb
   cpc      _r_t2_last_hb, _r_t2_hb
   brlo   _clr_r_t2_last
   sub      _r_t2_last_lb, _r_t2_lb
   sbc      _r_t2_last_hb, _r_t2_hb
   rjmp   _calc_r_t2_last_end
_clr_r_t2_last:
   clr      _r_t2_last_lb
   clr      _r_t2_last_hb
_calc_r_t2_last_end:

   ; тут в _r_t1_hb:_r_t1_lb уже нужное число для передачи - ничего не делаем

   rcall    VALUE_transmit_RS232
   ldi      _r_transmit_data, KOI_8_semicolon
   rcall    DATA_transmit_RS232               ; символ ";"

   mov      _r_t1_lb, _r_t1_last_lb
   mov      _r_t1_hb, _r_t1_last_hb
   rcall    VALUE_transmit_RS232
   ldi      _r_transmit_data, KOI_8_semicolon
   rcall    DATA_transmit_RS232               ; символ ";"

   mov      _r_t1_lb, _r_t2_lb
   mov      _r_t1_hb, _r_t2_hb
   rcall    VALUE_transmit_RS232
   ldi      _r_transmit_data, KOI_8_semicolon
   rcall    DATA_transmit_RS232               ; символ ";"

   mov      _r_t1_lb, _r_t2_last_lb
   mov      _r_t1_hb, _r_t2_last_hb
   rcall    VALUE_transmit_RS232

   ; счетчик измерений считает от 0 вверх
   ; если он четный - в конце передаем ";", иначе переход на новую строку

   sbrc   _r_count_measure_sets, 0
   rjmp   MEASURE_transmit_RS232_SEND_TO_PC_new_line
   
   ldi      _r_transmit_data, KOI_8_semicolon
   rcall    DATA_transmit_RS232               ; символ ";"

   rjmp   MEASURE_transmit_RS232_END

MEASURE_transmit_RS232_SEND_TO_PC_new_line:

   ldi      _r_transmit_data, KOI_8_ps
   rcall    DATA_transmit_RS232
   ldi      _r_transmit_data, KOI_8_vk
   rcall    DATA_transmit_RS232               ; переход на новую строку

MEASURE_transmit_RS232_END:

   ret
;--------------------------------------------------------------------

INITIALIZE_MEASURE:

   ; вынес в процедуру ИСКЛЮЧИТЕЛЬНО из-за ограничения количества строк перехода!

   clr    _r_count_measure_time_lb   
   clr    _r_count_measure_time_hb

   ser    _r_t1_lb
   ser    _r_t1_hb
   ser    _r_t2_lb
   ser    _r_t2_hb

   ; используем тут _r_transmit_data для начального состояния входов
   in      _r_transmit_data, PINB

   in       _r_mom, MCUCR
   cbr    _r_mom, (1<<SM0) + (1<<SM1)
   sbr    _r_mom, (1<<SE)
   out    MCUCR, _r_mom      ; задаем режим sleep-а Idle и устанавливаем флаг его разрешения

   ldi    _r_mom, _one_measure_time - 1 - 8 - 4 - 8
   out    OCR0A, _r_mom      ; значение счетчика таймера для прерывания
                        ; 1 - на установку флага прерывания
                        ; 8 - на переход на адрес вектора прерывания
                        ; 4 - на reti с адреса вектора прерывания
                        ; 8 = 2 на сброс счетчика таймера + 6 на проверку условия цикла
   clr    _r_mom
   out    TCNT0, _r_mom      ; сброс счетчика таймера
   ldi    _r_mom, (1<<OCIE0A)
   out    TIMSK0, _r_mom      ; разрешаем прерывание по счетчику таймера
   ldi    _r_mom, (0<<CS02) + (0<<CS01) + (1<<CS00)
   out    TCCR0B, _r_mom      ; запускаем таймер с частотой СК

   sei

   ret
;--------------------------------------------------------------------

MAIN:

   cbi      PORTB, _PIN_RELE_OUT1
   cbi      PORTB, _PIN_RELE_OUT2   
   sbi      PORTB, _PIN_PC_OUT      ; инициализируем передачу на комп

;   ldi    _r_mom, (1<<PCIE)
;   out    GIMSK, _r_mom         ; разрешаем прерыванияпо изменению состояния выводов

;   in       _r_mom, MCUCR
;   cbr    _r_mom, (1<<SM0)
;   sbr    _r_mom, (1<<SM1) + (1<<SE)
;   ;ldi    _r_mom, (0<<ISC00) + (0<<ISC01) + (0<<SM0) + (0<<SM1) + (1<<SE) + (0<<PUD)
;   out    MCUCR, _r_mom      ; задаем режим sleep-а Power-down и устанавливаем флаг его разрешения

;   sei

;   sleep                  ; Power-down

   ; тут проснемся от прерывания PIN_CHANGE
      
   ldi    _r_WAIT, 20 ; 37.5 Гц
   rcall    WAIT_Idle         ; ждать 1s

   ; инициализировать контакты реле

   sbi      PORTB, _PIN_RELE_OUT2

   ldi    _r_WAIT, 6 ; 37.5 Гц
   rcall    WAIT_Idle         ; ждать 250ms

   cbi      PORTB, _PIN_RELE_OUT2

   ldi    _r_WAIT, 6 ; 37.5 Гц
   rcall    WAIT_Idle         ; ждать 250ms

   ; провести серию измерений, записывая результаты каждого в EEPROM

   clr    _r_count_measure_sets

SET_OF_MEASURES:

   rcall    INITIALIZE_MEASURE

   ; команда на переключение - инвертируем _PIN_RELE_OUT1
   ldi      _r_WAIT, (1<<_PIN_RELE_OUT1)
   in      _r_mom, PORTB
   eor      _r_mom, _r_WAIT
   out      PORTB, _r_mom

   ; измеряем t1 и t2

MEASURE:                  ; опрос пинов строго раз в 10us = 96 тактов
                        ; таких опросов строго до достижения _max_measure_time
   clr    _r_mom
   out    TCNT0, _r_mom      ; сброс счетчика таймера

   ; тут у нас есть на все наши операции максимум 96 - 1 - 8 - 4 - 8 = 75 тактов!

;   ldi      _r_mom, 25
;a3:   dec      _r_mom
;   brne   a3
;   ; 75 тактов
;   ;nop
;   ;nop
;   nop

   ldi      _r_mom, 1
   clr    _r_WAIT
   add      _r_count_measure_time_lb, _r_mom
   adc      _r_count_measure_time_hb, _r_WAIT   ; инкремент счетчика

   ; манипуляции с _r_mom, после которых в битах _PIN_RELE_IN1 и _PIN_RELE_IN2
   ; будут 1-цы только если текущие значения не равны начальным из _r_transmit_data
   in      _r_mom, PINB
   eor      _r_mom, _r_transmit_data

   ; старшие байты _r_t1_hb и _r_t2_hb изначально забиты 1-цами
   ; а после занесения в них значений измерения - гарантированно меньше,
   ; т.к. максимальное значение у нас будет 3000 а возможное - 65536

   cpi      _r_t1_hb, 255
   brne   MEASURE_t1_END         ; пропускаем если _r_t1_hb <> 255 - уже заполнили

   sbrs   _r_mom, _PIN_RELE_IN1
   rjmp   MEASURE_t1_END         ; пропускаем если состояние не изменилось

   mov      _r_t1_lb, _r_count_measure_time_lb
   mov      _r_t1_hb, _r_count_measure_time_hb

MEASURE_t1_END:

   cpi      _r_t2_hb, 255
   brne   MEASURE_t2_END         ; пропускаем если _r_t2_hb <> 255 - уже заполнили

   sbrs   _r_mom, _PIN_RELE_IN2
   rjmp   MEASURE_t2_END         ; пропускаем если состояние не изменилось

   mov      _r_t2_lb, _r_count_measure_time_lb
   mov      _r_t2_hb, _r_count_measure_time_hb

MEASURE_t2_END:

   ; каждый цикл записываем тек. время если состояние вывода РАВНО исходному
   ; - так отследим время окончания дребезга

   sbrc   _r_mom, _PIN_RELE_IN1
   rjmp   MEASURE_t1_last_END      ; пропускаем если состояние изменилось

   mov      _r_t1_last_lb, _r_count_measure_time_lb
   mov      _r_t1_last_hb, _r_count_measure_time_hb

MEASURE_t1_last_END:

   sbrc   _r_mom, _PIN_RELE_IN2
   rjmp   MEASURE_t2_last_END      ; пропускаем если состояние изменилось

   mov      _r_t2_last_lb, _r_count_measure_time_lb
   mov      _r_t2_last_hb, _r_count_measure_time_hb

MEASURE_t2_last_END:

   ; заняли максимум 40 тактов

   sleep

   ldi      _r_mom,  low(_max_measure_time)
   ldi      _r_WAIT, high(_max_measure_time)
   cp      _r_count_measure_time_lb, _r_mom
   cpc      _r_count_measure_time_hb, _r_WAIT
   brlo   MEASURE
   
   ; прошли _max_measure_time - сделали очередное измерение
   cli

   in       _r_mom, MCUCR
   cbr    _r_mom, (1<<SE)
   out    MCUCR, _r_mom      ; сбрасываем флаг разрешения sleep-а

   clr    _r_mom
   out    TCCR0B, _r_mom      ; останавливаем таймер
   out    TCNT0, _r_mom      ; сброс счетчика таймера

   ldi    _r_WAIT, 6 ; 37.5 Гц
   rcall    WAIT_Idle         ; ждать 250ms
   
   ; команда на исходное положение - инвертируем _PIN_RELE_OUT2
   ldi      _r_WAIT, (1<<_PIN_RELE_OUT2)
   in      _r_mom, PORTB
   eor      _r_mom, _r_WAIT
   out      PORTB, _r_mom

   ; передать результаты на комп
   rcall   MEASURE_transmit_RS232
      
   ldi    _r_WAIT, 6 ; 37.5 Гц
   rcall    WAIT_Idle         ; ждать 250ms
   
   ; если ещё не все измерения сделаны (а одно измерение - это сначала туда а потом обратно)
   ; то сделаем ещё измерение
   inc      _r_count_measure_sets
   cpi      _r_count_measure_sets, 2*_sets_of_measures
   brlo   SET_OF_MEASURES
   
   ; провели серию измерений и передали результаты на комп -
   ; готовы к новой серии измерений (на старт и PowerDown)

   ;rjmp    MAIN

   ; нет - тут падаем в Power-down без права прерывания и ждем RESET :)))

SLEEP_Power_down:

   cli

   in       _r_mom, MCUCR
   cbr    _r_mom, (1<<SM0)
   sbr    _r_mom, (1<<SM1) + (1<<SE)
   ;ldi    _r_mom, (0<<ISC00) + (0<<ISC01) + (0<<SM0) + (0<<SM1) + (1<<SE) + (0<<PUD)
   out    MCUCR, _r_mom      ; задаем режим sleep-а Power-down и устанавливаем флаг его разрешения

   sleep                  ; Power-down

   rjmp    SLEEP_Power_down

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 22:09 
Заслуженный участник


27/04/09
28128
Кошмар! :shock: Неужели более общо (ну хотя бы в обратном порядке: 10, 100, …) ну совсем медленно неспортивно неканонично нехорошо будет?

-- Ср дек 19, 2012 01:10:56 --

Вообще, вводят-выводят числа ведь гораздо реже, чем делают с ними арифметику.

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 22:26 
Аватара пользователя


31/10/08
1244
g_coder
Читайте книги в них всё это расписано. А вообще найти ответ в интернете очень легко. И странно что вы его не нашли.
Формат строк известен формат числа известен перевести из одного формата в другой это простая задачка.
На данном форуме решать задачи за других не принято. А вот помочь да. В данном случае ваших попыток решения не видно.

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 22:55 


05/09/12
2587
arseniiv а зачем делать неоптимально? Форматированный вывод заданной длины с незначащими нулями и фиксированной точкой, вполне спортивно, дешево, надежно и практично :-) И главное, без единого гвоздя использования ОЗУ (а есть контроллеры, где нет ОЗУ и Си не работает). наоборот - это нарезать и заполнять массив, а тут - вывел разряд и забыл.

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:10 
Аватара пользователя


27/01/09
814
Уфа
А делить на 10 не судьба?

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:13 
Заслуженный участник


27/04/09
28128
_Ivana, можно и в стек складывать.

_Ivana в сообщении #660432 писал(а):
а есть контроллеры, где нет ОЗУ
А есть контроллеры, где вообще жутко другой набор команд… :roll:

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:20 


05/09/12
2587
arseniiv вот скажите честно, вам надо 5 цифр вывести - вы будете считать разряды с конца и в стек складывать?

Chifu у каждого своя судьба. Если такая судьба, что есть аппаратное деление, то можно и делить. Но не всегда и аппаратное умножение есть.

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:24 
Заслуженный участник


27/04/09
28128
_Ivana в сообщении #660446 писал(а):
arseniiv вот скажите честно, вам надо 5 цифр вывести - вы будете считать разряды с конца и в стек складывать?
Да, я так делал. :roll: Нету во мне духа ассемблера… О боже, я делил!

(Оффтоп)

:-)

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:32 


05/09/12
2587
Ну я тоже не хранитель духа ASM :-) Но в данном примере сделал так. И все равно не понимаю, чем этот подход заслуживает такие эпитеты. Выложите код вашей процедуры вывода, приобщусь к стереотипам :-)

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:41 
Заслуженный участник


09/09/10
3729
Товарищи, окститесь. TASM — это 99% за то, что топикстартер мучает real-mode x86. Возможно, даже без DOS.

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение19.12.2012, 00:02 
Заслуженный участник


27/04/09
28128
_Ivana в сообщении #660453 писал(а):
Выложите код вашей процедуры вывода, приобщусь к стереотипам
Скорее всего, он уже не со мной. :-)

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение19.12.2012, 00:07 


05/09/12
2587
Ну вот, как эпитетами награждать и к универсальности призывать, так все тут как тут, а как выложить свой код в качестве примера правильного, так вон оно что :-)

 Профиль  
                  
 
 Re: ASM вывод числа на экран
Сообщение19.12.2012, 00:13 
Заслуженный участник


27/04/09
28128
Там было деление, остаток (есть же инструкция для их одновременного выполнения вроде?) и от младших цифр к старшим, потом через стек это на экран, обработка нуля отдельная, значения из изменяемых регистров сохранялись на время выполнения других инструкций процедуры в стеке. Что тут особенно интересного?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 25 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group