Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 342
∙ повысить рейтинг »
Куликов Роман Евгеньевич
Статус: 1-й класс
Рейтинг: 0
∙ повысить рейтинг »
Козлова Ольга Александровна
Статус: 1-й класс
Рейтинг: 0
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler

Номер выпуска:1602
Дата выхода:22.04.2016, 17:21
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:18 / 7
Вопросов / ответов:2 / 2

Консультация # 189164: Уважаемые эксперты! Прошу вас помочь с составлением программы для CompModel. Разность сумм четных и нечетных элементов массива; 11. Заранее - большое спасибо! ...
Консультация # 189210: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Нужно написать программу для TASM Рассчитать и вывести значения выражения,при заданных пользователем значения x и a. Y=3*6+4*4/(sin(a)*3)*(48+16/2)*(5+8*cos(x)/14-3) ...

Консультация # 189164:

Уважаемые эксперты! Прошу вас помочь с составлением программы для CompModel. Разность сумм четных и нечетных элементов массива; 11.
Заранее - большое спасибо!

Дата отправки: 12.04.2016, 13:29
Вопрос задал: freeflowmc (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, freeflowmc!
Вот и программа. Начиная с адреса 40, надо будет записать 10 значений, например: 1,2,3,4,5,6,7,8,9,10

Код (Assembler) :: выделить код
RD #40 ;стартовый адрес массива
WR R0  ;в регистре R0
RD #10 ;количество
WR R1  ;в R1
RD #0  ;сумма 
WR R2  ;четных
WR R3  ;нечетных
LOOP:RD @R0+ ;читаем очередного, с автоинкрементом адреса
WR R4  ;сохраним в R4
DIV #2 ;вот тут самое "хитрое" место: так как нет ни команд сдвига, ни логических
MUL #2 ;то пришлось разделить на 2, потом умножить на 2 и результат  сравнить с исходным
SUB R4 ;если не равны, то нечетное!
JNZ ODD;нечетное
RD R4  ;четное
ADD R2 ;накапливаем сумму четных
WR R2
JMP NEXT ;на продолжение цикла
ODD:RD R4;нечетное
ADD R3  ;накапливаем сумму
WR R3
NEXT:JRNZ R1,LOOP ;повторяем R1 раз
RD R2  ;сумма четных
SUB R3 ;минус сумма нечетных
OUT
HLT

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 19.04.2016, 00:03
Рейтинг ответа:

НЕ одобряю +1 одобряю!

Консультация # 189210:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:

Нужно написать программу для TASM

Рассчитать и вывести значения выражения,при заданных пользователем значения x и a.

Y=3*6+4*4/(sin(a)*3)*(48+16/2)*(5+8*cos(x)/14-3)

Дата отправки: 17.04.2016, 14:41
Вопрос задал: DRAGUN (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, DRAGUN!
Программа работает с вещественными числами, считает в сопроцессоре

Код (Assembler) :: выделить код
   .model   small
   .data 
sEnterA   db   "Enter a = $"   ;приглашение ввести а 
sEnterX   db   "Enter x = $"   ;приглашение ввести х 
sY   db   "y = $"      ;вывод y 
c10   dw   10      ; 10 основание системы счисления 
            ;числа-константы из формулы 
c3   dw   3 
c6   dw   6 
c4   dw   4 
c48  dw   48 
c16  dw   16 
c2   dw   2 
c5   dw   5
c8   dw   8
c14  dw   14 
            ;буфер для ввода строки-вещественного числа 
max   db   64      ;размер буфера 
len   db   ?      ;реальная длина 
String db   64 dup (?)   ;сама строка 
 
sTemp  db   64 dup(?)   ;временный буфер для формирования строки-числа 
dig    dw   ?      ;цифра при обмене с сопроцессором 
 
a   dd   ?      ;числа, которые вводятся 
x   dd   ?
 
   .code         ;сегмент кода 
   .386         ;необходимо для команды fsin и fcos
   .startup      ;инициализация сегментов для выбранной модели памяти 
 
   lea    dx, sEnterA
   call   InputFloat   ;вводим a 
   fstp   a      ;сохраним из стека сопроцессора в переменной а 
 
   lea    dx, sEnterX
   call   InputFloat   ;вводим x 
   fstp   x
 
   lea    dx, sY      ;выведем строку "y = " 
   mov    ah, 9 
   int    21h
 
   call   CalcY      ;считаем y по формуле, результат в стеке сопроцессора 
 
   call   float2str   ;преобразуем вещ число в стеке сопроцессора в строку 
 
   lea    dx, String   ;и выведем 
   mov    ah, 9 
   int    21h
 
   mov    ah, 0      ;ждем нажатие на клавишу 
   int    16h
   .exit  0 
 
CalcY   proc         ;расчет по формуле 
   fild   C3	;3 
   fimul  C6	;3*6 
 
   fild   C4	;4
   fimul  C4	;4*4
   
   fld    a	;a 
   fsin	;sin(a)
   fimul  C3	;sin(a)*3

   fdivp	;4*4/sin(a)*3
   
   fild   C48	;48
   fild   C16	;16
   fidiv  C2	;16/2
   faddp	;48+16/2
   
   fmulp	;(4*4/sin(a)*3)(48+16/2)
   
   fild   C5	;5
   fld	   x	;x
   fcos	;cos(x)
   fimul  C8	;8cos(x)
   fidiv  C14	;8cos(x)/14
   faddp	;5+(8cos(x)/14)
   fisub  C3	;5+(8cos(x)/14)-3
   
   fmulp	;(4*4/sin(a)*3)(48+16/2)(5+(8cos(x)/14)-3)
   
   faddp	;3*6 + (4*4/sin(a)*3)(48+16/2)(5+(8cos(x)/14)-3)
   ret 
CalcY   endp 
 
InputFloat   proc      ;ввод вещественного числа 
   push   dx      ;сохраним адрес приглашения для повторного ввода 
   mov   ah, 9      ;выведем строку приглашения 
   int   21h
   
   lea   dx, max      ;вводим строку 
   mov   ah, 0ah
   int   21h
 
   lea   si, String   ;адрес строки 
   call   str2float   ;преобразовываем во float с проверкой синтаксиса 
   pushf         ;флаг С говорит о корректности строки, сохраним флажки 
   mov   ah, 2 
   mov   dl, 0dh      ;перевод на новую строку 
   int   21h
   mov   dl, 0ah
   int   21h
   popf         ;восстановим флажки 
   pop   dx      ;восстановим (уберем из стека) адрес приглашения 
   jc   InputFloat   ;ошибка - на повтор ввода! 
   ret         ;введенное число в стеке сопроцессора 
InputFloat   endp 
   
;Преобразование строки в вещественное число в st сопроцессора 
str2float   proc      ;преобразование строки в вещественное число 
   fldz         ;подготовим st=0 
   xor   dx, dx      ;число знаков после точки = 0 
   xor   bx, bx      ;bl = 0/1 знак числа +/-, bh = 1/0 знак уже введен/не задан 
   xor   di, di      ;число введенных цифр, для контроля позиции знака 
s2fNext:
   lodsb         ;очередной символ 
   cmp   al, 0dh      ;дошли до конца? 
   je   s2fSign      ;учтем знак 
   cmp   al, '+'      ;плюс? 
   jne   s2f_minus
   cmp   bh, 0      ;знак уже был введен? 
   jne   s2f_err      ;можно только раз 
   test   di, di 
   jne   s2f_err      ;знак можно писать только в первой позиции 
   mov   bh, 1      ;знак задан 
   jmp   s2fNext
s2f_minus:
   cmp   al, '-'      ;минус? 
   jne   s2f_point
   cmp   bh, 0      ;знак уже был введен? 
   jne   s2f_err      ;можно только раз 
   test   di, di 
   jne   s2f_err      ;знак можно писать только в первой позиции 
   mov   bx, 0101h   ;задаем знак - минус 
   jmp   s2fNext
s2f_point:
   cmp   al, '.'      ;точка 
   jne   s2f_digit
   test   dx, dx      ;точку можно задать только один раз 
   jne   s2f_err
   jmp   s2fInc
s2f_digit:         ;проверка на цифры 
   cmp   al, '0' 
   jb   s2f_err
   cmp   al, '9' 
   ja   s2f_err   
   inc   di      ;есть цифра 
   and   ax, 0fh      ;готовим разряд  
   mov   dig, ax      ; для загрузки в сопроцессор 
   test   dx, dx      ;если целая часть, то 
   je   s2fMul10   ; на умножение на 10 
   mov   cx, dx      ;иначе делим dx раз на 10 
   fild   dig      ; очередной разряд 
s2fdiv:
   fidiv   c10      ;делим dх раз 
   loop   s2fdiv
   faddp         ;складываем разряд за точкой с формируемым числом 
s2fInc:
   inc   dx      ;для точки только увеличиваем dх 
   jmp   s2fNext      ;пока не дойдем до конца 
 
s2fMul10:         ;целое число 
   fimul   c10      ;умножаем старое на 10 
   fiadd   dig      ;и прибавляем очередной разряд 
   jmp   s2fNext
s2fSign:         ;ввод числа закончен, учтем знак 
   cmp   bl, 0      ;если - 
   je   s2fRet
   fchs         ;то меняем знак 
s2fRet:
   clc         ;все ок 
   ret 
s2f_err:
   stc         ;ошибочка 
   fstp   st      ;выкидаем из стека число 
   ret 
str2float   endp 
 
;преобразование вещественного числа из st в строку по адресу String 
float2str   proc 
   push   es 
   push   ds 
   pop   es      ;es=ds 
 
   lea   di, sTemp   ;здесь будем формировать строку 
   ftst         ;Проверяем число 
   fstsw   ax      ;флаги в ax 
   sahf         ;флаги в регистре флагов 
   jnz   f2s_notZero   ;не 0 
   mov   dx, 1      ;длина 1 
   mov   bl, 0      ;сбрасываем знак 
   mov   ax, '0'      ;если 0, то выводим 0 
   stosw 
   jmp   f2s_Ret      ;на выход 
 
f2s_notZero:         ;не 0 
   mov   al, ' '      ; пока считаем, что положительное 
   jnc   f2s_sign   ;если оно отрицательное, 
   mov   al, '-'      ; то минус 
   fchs         ; и оставляем модуль числа. 
f2s_sign:
   stosb         ;знак числа 
; Пояснение далее пойдёт на примере.   ; ST(0) ST(1) ST(2) ST(3) ... 
; Отделим целую часть от дробной.   ; 73.25 ... что-то не наше 
   fld1            ;  1   73.25 ... 
   fld   st(1)         ; 73.25  1    73.25 ... 
; Остаток от деления на единицу даст дробную часть. 
   fprem            ;  0.25  1    73.25 ... 
; Если вычесть её из исходного числа, получится целая часть. 
   fsub   st(2), st      ;  0.25  1    73    ... 
   fxch   st(2)         ; 73     1     0.25 ... 
; Сначала поработаем с целой частью. Считать количество цифр будем в CX. 
   xor   cx, cx 
; Поделим целую часть на десять, 
f2s_2:   fidiv   c10         ;  7.3   1     0.25 ... 
   fxch   st(1)         ;  1    7.3   0.25 ... 
   fld   st(1)         ;  7.3    1     7.3  0.25 ... 
; отделим дробную часть - очередную справа цифру целой части исходного числа,- 
   fprem            ;  0.3    1     7.3  0.25 ... 
; от чатсного оставим только целую часть 
   fsub   st(2), st      ;  0.3    1     7    0.25 ... 
; и сохраним цифру 
   fimul   c10         ;  3    1     7    0.25 ... 
   fistp   dig         ;  1    7     0.25 ... 
   inc   cx 
; в стеке. 
   push   dig
   fxch   st(1)         ;  7    1     0.25 ... 
; Так будем повторять, пока от целой части не останется ноль. 
   ftst 
   fstsw   ax 
   sahf 
   jnz   f2s_2
; Теперь выведем её. 
f2s_3:   pop   ax 
; Вытаскиваем очередную цифру, переводим её в символ и выводим. 
   add   al, 30h
   stosb 
; И так, пока не выведем все цифры. 
   loop   f2s_3           ;  0    1     0.25 ... 
; Итак, теперь возьмёмся за дробную часть, для начала проверив её существование. 
   fstp   st(0)         ;  1    0.25 ... 
   fxch   st(1)          ;  0.25  1    ... 
   ftst 
   fstsw   ax 
   sahf 
   jz   f2s_5
; Если она всё-таки ненулевая, выведем точку 
   lea   ax, sTemp
   mov   cx, di 
   sub   cx, ax 
   sub   cx, 63 
   neg   cx 
   mov   al, '.' 
   stosb 
; Помножим дробную часть на десять 
f2s_4:   fimul   c10         ;  2.5    1    ... 
   fxch   st(1)         ;  1    2.5  ... 
   fld   st(1)          ;  2.5    1     2.5  ... 
; отделим целую часть - очередную слева цифру дробной части исходного числа,- 
   fprem            ;  0.5    1     2.5  ... 
; оставим от произведения лишь дробную часть 
   fsub   st(2), st      ;  0.5    1     2    ... 
   fxch   st(2)          ;  2    1     0.5  ... 
; сохраним полученную цифру во временной ячейке 
   fistp   dig         ;  1    0.5  ... 
; и сразу выведем. 
   mov   ax, dig
   add   al, 30h
   stosb 
; Теперь, если остаток дробной части ненулевой 
   fxch   st(1)         ;  0.5    1    ... 
   ftst 
   fstsw   ax 
   sahf 
; и мы вывели менее cx цифр, продолжим 
   loopnz  f2s_4          ;  0    1    ... 
; Итак, число выведено. Осталось убрать мусор из стека. 
f2s_5:   fstp   st(0)         ;  1   ... 
   fstp   st(0)         ;  ... 
   mov   byte ptr [di], '$'   ;закроем строку знаком '$' для функции 9 
; и скопировать в буфер String не более 14 знаков 
   lea   si, sTemp
   lea   di, String 
   mov   dx, 0      ;длина 
f2s_6:
   lodsb 
   stosb            ;копируем 1 байт 
   inc   dx         ;считаем 
   cmp   dx, 14         ;копируем только 14 байт !!! (если получится число 
               ; с большим чем 14 байт знаков, то последние усекутся) 
   je   f2s_7         ;насильно закрываем '$'! 
   cmp   al, '$' 
   jne   f2s_6         ;копирование завершаем по '$' 
   dec   dx         ;отнимем 1 (посчитался байт '$') 
f2s_7:
   mov   byte ptr [di], '$'   ;закроем '$' (для случая обрезания) 
f2s_Ret:
   pop   es 
   ret 
float2str   endp 
   end

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 18.04.2016, 18:41
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное