WMmail.ru - сервис почтовых рассылок

четверг, 17 декабря 2015 г.

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

 
Если выпуск не отображается, вы можете прочесть его на сайте
  
  
Получите бесплатное руководство по работе на Forex и начните зарабатывать
  

  
Grand Callas walnut Grand Callas walnut
Купить за 754000 руб. Подробнее...

  Targa HDTV (92"/16:9) 114x203 MW (моторизированный Targa HDTV (92"/16:9) 114x203 MW (моторизированный
Купить за 81695 руб. Подробнее...

  Targa HDTV (106"/16:9) 132x234 HCG (моторизированн Targa HDTV (106"/16:9) 132x234 HCG (моторизированн
Купить за 67578 руб. Подробнее...

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

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

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

Асмик Гаряка
Статус: Советник
Рейтинг: 11125
• повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Советник
Рейтинг: 5020
• повысить рейтинг »
Куликов Роман Евгеньевич
Статус: 1-й класс
Рейтинг: 0
• повысить рейтинг »

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

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

Консультация # 188411: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: По запросу программы пользователь вводит с клавиатуры два целых четырехзначных положительных десятичных числа, разделённых знаком операции + или - Программа выводит на экран результат операции в двух системах счисления : в десятичной и бинарной (в дополнительном коде).<...


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

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
По запросу программы пользователь вводит с клавиатуры два целых четырехзначных положительных десятичных числа, разделённых знаком операции + или -
Программа выводит на экран результат операции в двух системах счисления : в десятичной и бинарной (в дополнительном коде).

Для перевода числа из десятичной системы счисления в любую другую воспользуйтесь алгоритмом вывода на экран десятичных и шестнадцатеричных чисел:


Ассемблер: Nasm

Спасибо.

Дата отправки: 13.12.2015, 00:45
Вопрос задал: surikalex007456 (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


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

Здравствуйте, surikalex007456!
Вот и программа. Работает как с положительными, так и с отрицательными числами
Комментариев более, чем достаточно. Вникайте...

Код (Assembler):
  format PE console    include 'win32ax.inc'    code    ;функция преобразует строку в число  ;первые пробелы пропускаются  ;ввод заканчивается любой нецифрой  ;параметры:  ;esi - адрес строки  ;ecx - длина строки  ;число возвращается в eax  proc	atoi uses edi ebx  	mov		ebx, 1			;знак числа, считаем, что положительное  	mov		edi, 10 		;будем умножать на 10  	xor		edx, edx		;здесь накапливаем число  first_spaces:				;цикл пропуска первых пробелов  	lodsb					;читаем символ из [esi], esi++  	dec		ecx				;уменьшаем счетчик  	jl		.atoi_ret		;строка кончилась  	cmp		al, ' ' 		;первые пробелы  	je		.first_spaces	; пропускаем    	cmp		al, '-' 		;встретили минус?  	jne		.atoi_next  	neg		ebx		 		;ebx = -1, отрицательное число  	lodsb					;читаем следующий символ  	dec		ecx				;уменьшаем счетчик  	jl		.atoi_ret		;строка кончилась    atoi_next:					;цикл обработки цифр  	cmp		al, '0' 		;проверяем на цифру  	jl		.atoi_ret  	cmp		al, '9'  	jg		.atoi_ret    	imul	edx, edi		;умножаем старшие разряды на 10  	and		eax, 0x0f		;и добавим  	add		edx, eax		; новый разряд  	lodsb					;читаем следующий символ  	dec		ecx				;счетчик  	jge    .atoi_next		;и на повтор    atoi_ret:  	dec		esi				;сдвинем указатель на предыдущий символ   							; для дальнейшего анализа  	inc		ecx				;подправим и счетчик  	mov		eax, edx		;вернем число  	imul	eax, ebx		;учтем знак числа  	ret  endp    ;функция анализирует символ операции  ;параметры:  ;esi - адрес строки  ;ecx - длина строки  ;код операции возвращается в eax и C=0  ;если символ операции неверный, то вернет C=1  proc	GetOp  	lodsb					;читаем символ  	dec		ecx				;счетчик  	jl		.error  	cmp		al, ' ' 		;пробелы игнорируем  	je		GetOp  	cmp		al, '-' 		;есть минус  	je		.minus  	cmp		al, '+' 		;плюс  	jne		.error  	xor		eax, eax		;для плюса возвращаем 0  	clc  	ret  minus:  	mov		eax, 1			;для минуса - 1  	clc  	ret   .error:  	stc  	ret  endp    ;функция парсит введенную строку и вычисляет операцию  ;параметры:  ;esi - адрес строки  ;ecx - длина строки  ;результат возвращается в eax и в С  proc	CalcCommand  	call	atoi			;получаем первое число  	mov		edi, eax		;сохраним в edi    	call	GetOp			;вводим код операции  	jc		.return 		;ошибка?  	mov		ebx, eax		;сохраняем в ebx    	call	atoi			;вводим второе число  							;проверим на корректность данных  	cmp		byte [esi], 0dh ;мы должны выйти из анализа либо по 0dh  	je		.test_op  	cmp		byte [esi], ' ' ;либо по пробелу  	stc						;вдруг ошибка!  	jne		.return 		;все остальное - ошибка формата!  							;все ок!  test_op:					;проверяем код операции  	xchg	eax, edi		;поменяем местами операнды  	test	ebx, ebx		;0 - плюс  	jz		.op_add  							;1 - минус  op_sub:  	sub		eax, edi  	jmp		.ret_ok  op_add:  	add		eax, edi  ret_ok:  	clc  return:  	ret  endp    ;функция преобразования числа в строку  ;параметры:  ;edi - адрес строки  ;eax - число  proc itoa     test 	eax, eax			;отрицательное?     jge		.positive     neg		eax					;модуль числа     mov		byte [edi], '-' 	;выводим знак минуса     inc		edi  positive:						;собственно преобразование     xor		ecx, ecx			;счетчик цифр  	mov		esi, 10 			;будем делить на 10  div_loop:						;цикл формирования десятичных разрядов  	xor		edx, edx			;подготавливаемся к делению  	div		esi					;eax - частное edx:eax/esi, edx - остаток  	push	edx					;остаток - очередной разряд - сохраняем в стеке  	inc		ecx					;считаем  	test	eax, eax			;все разряды?  	jne		.div_loop			;нет - на повтор  digits_loop:					;цикл вывода цифр, извлекаем из стека в обратном порядке  	pop		eax					;очередной разряд     or		al, '0' 			;делаем символ-цифру  	stosb						;выводдим  	loop	.digits_loop		;по всем  	ret  endp    ;функция формирования двоичной строки  ;параметры:  ;eвi - адрес строки  ;eax - число  proc	form_bin  	mov		edx, eax			;перенесем число для удовства в edx  	mov		ecx, 32 			;32 бита  shift_loop:					;цикл по битам  	mov		al, '0' 			;al = '0'  	shl		edx, 1				;C - очередной бит  	adc		al, 0				;al = '0' + 0 + C ('0' или '1')  	stosb  	loop	.shift_loop			;по всем  	mov		ax, 'b' 			;строку закончим 'b' с нулем! (ah=0)  	stosw  	ret  endp    ;---------------------------------------------------  ;Начало  start:  ;получим handle консоли для вывода  	invoke	GetStdHandle, STD_OUTPUT_HANDLE  	cmp		eax,-1  	je		.console_error_exit  	mov		[hStdOut], eax		;сохраним    ;получим handle консоли для ввода  	invoke	GetStdHandle, STD_INPUT_HANDLE  	cmp		eax,-1  	je		.console_error_exit  	mov		[hStdIn], eax		;сохраним    ;выводим приглашение для ввода строки  	invoke	WriteConsole, [hStdOut], szMessage, MsgLen, dwWritten, 0  ;вводим строку в буфер sCommand, длина введенной строки будет в dwReaded  	invoke	ReadFile, [hStdIn], sCommand, 64, dwReaded, 0    ;обрабатываем строку  	lea		esi, [sCommand]  	mov		ecx, [dwReaded]  	call	CalcCommand  	jc		.error_exit			;ошибка?    ;формируем результат, число в eax  	lea		edi, [sCommand] 	;сюда запишем строку результат  	push	eax					;сохраним число для вывода двоичной стоки  	call	itoa				;преобразуем в строку-знаковое десятичное число  	mov		ax, ', '			;отделим запятой с пробелом  	stosw  	pop		eax					;восстановим полученное число  	call	form_bin			;формируем двоичную строку    ;выведем полученнфй результат, начиная с пояснительной строки  ;третьим параметром передается результат вызова подсчета длины строки  ;invoke lstrlen, sResult  	invoke	WriteConsole, [hStdOut], sResult, invoke lstrlen, sResult, dwWritten, 0  	jmp	short .wait_enter    error_exit:  	invoke	WriteConsole, [hStdOut], szError, ErrLen, dwWritten, 0  	  wait_enter:  ;ждем нажатие на enter, чтобы не убежало с экрана  	invoke	ReadFile, [hStdIn], sCommand, 1, dwReaded, 0  	jmp	short .exit  	  console_error_exit:  ;При ошибке получения handle консоли выведем MessageBox, в заголовке путь и имя программы  	invoke	MessageBox,HWND_DESKTOP,"Error occured",invoke GetCommandLine,MB_OK    exit:  	invoke	ExitProcess,0    data    hStdOut 	dd	-1  hStdIn		dd	-1    szMessage	db "Enter operation: "  MsgLen = $-szMessage    szError 	db	"Incorrect command!"  ErrLen = $-szError    dwWritten	dd	0  dwReaded	dd	0    sResult 	db	"Result: "  sCommand	db	64 dup(?)    end start  

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

5
нет комментария
-----
Дата оценки: 15.12.2015, 21:36

Рейтинг ответа:

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


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

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

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

 
     Прошлые выпуски
RFpro.ru: Ассемблер? Это просто! Учимся программироватьRFpro.ru: Ассемблер? Это просто! Учимся программироватьRFpro.ru: Ассемблер? Это просто! Учимся программироватьВсе выпуски рассылки
 
 
Subscribe.Ru / АО «Интернет-Проекты» / О компании / Политика конфиденциальности

Комментариев нет:

Отправить комментарий