2014 dxdy logo

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

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




На страницу 1, 2  След.
 
 ASM вывод числа на экран
Сообщение18.12.2012, 19:25 
Доброго времени суток!
Я не так давно начал изучать ассемблер и сейчас у меня возникла проблема с выводом чисел на экран.
Гуглил много, но ничего подходящего не нашел, лишь узнал что для вывода числа его сначала нужно преобразовать в строку. Так вот хотелось бы узнать каким образом можно некоторое число конвертировать в строчку и вывести. Если вы знаете, другие способы вывода числа на экран, то прошу написать, ибо это будет весьма полезно.

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

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 19:39 
Аватара пользователя
Научитесь вызывать функции из libc , a дальше -- по старому.

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 20:20 
Берем число (например, двухбайтовое целое), пока оно больше 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 
Кошмар! :shock: Неужели более общо (ну хотя бы в обратном порядке: 10, 100, …) ну совсем медленно неспортивно неканонично нехорошо будет?

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

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

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 22:26 
Аватара пользователя
g_coder
Читайте книги в них всё это расписано. А вообще найти ответ в интернете очень легко. И странно что вы его не нашли.
Формат строк известен формат числа известен перевести из одного формата в другой это простая задачка.
На данном форуме решать задачи за других не принято. А вот помочь да. В данном случае ваших попыток решения не видно.

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

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

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:13 
_Ivana, можно и в стек складывать.

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

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:20 
arseniiv вот скажите честно, вам надо 5 цифр вывести - вы будете считать разряды с конца и в стек складывать?

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

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:24 
_Ivana в сообщении #660446 писал(а):
arseniiv вот скажите честно, вам надо 5 цифр вывести - вы будете считать разряды с конца и в стек складывать?
Да, я так делал. :roll: Нету во мне духа ассемблера… О боже, я делил!

(Оффтоп)

:-)

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:32 
Ну я тоже не хранитель духа ASM :-) Но в данном примере сделал так. И все равно не понимаю, чем этот подход заслуживает такие эпитеты. Выложите код вашей процедуры вывода, приобщусь к стереотипам :-)

 
 
 
 Re: ASM вывод числа на экран
Сообщение18.12.2012, 23:41 
Товарищи, окститесь. TASM — это 99% за то, что топикстартер мучает real-mode x86. Возможно, даже без DOS.

 
 
 
 Re: ASM вывод числа на экран
Сообщение19.12.2012, 00:02 
_Ivana в сообщении #660453 писал(а):
Выложите код вашей процедуры вывода, приобщусь к стереотипам
Скорее всего, он уже не со мной. :-)

 
 
 
 Re: ASM вывод числа на экран
Сообщение19.12.2012, 00:07 
Ну вот, как эпитетами награждать и к универсальности призывать, так все тут как тут, а как выложить свой код в качестве примера правильного, так вон оно что :-)

 
 
 
 Re: ASM вывод числа на экран
Сообщение19.12.2012, 00:13 
Там было деление, остаток (есть же инструкция для их одновременного выполнения вроде?) и от младших цифр к старшим, потом через стек это на экран, обработка нуля отдельная, значения из изменяемых регистров сохранялись на время выполнения других инструкций процедуры в стеке. Что тут особенно интересного?

 
 
 [ Сообщений: 25 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group