Calculadora en Ensamblador, Sumar, Restar, Multiplicar, Div

Instalación y preguntas sobre distribuciones, instalación, mantenimiento, trucos, etc.
Pregunton
Mensajes: 6
Registrado: Dom Jul 28, 2013 11:10 pm

Calculadora en Ensamblador, Sumar, Restar, Multiplicar, Div

Mensajepor Pregunton » Dom Jul 28, 2013 11:17 pm

Este sería un ejemplo, un poco completito, tal vez a alguien le venga bien:

Código: Seleccionar todo


; este ejemplo toma dos numero del usuario
; y calcula la suma de los dos numeros.
; luego imprime la salida.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; these maros are copied from emu8086.inc ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; this macro prints a string that is given as a parameter, example:
; PRINTN 'hello world!'
; the same as PRINT, but new line is automatically added.
  PRINTN MACRO sdat
  LOCAL next_char, s_dcl, printed, skip_dcl
 
  PUSH AX ; store registers...
  PUSH SI ;
 
  JMP skip_dcl ; skip declaration.
  s_dcl DB sdat, 13, 10, 0
 
skip_dcl:
  LEA SI, s_dcl
 
next_char:
  MOV AL, CS:[SI]
  CMP AL, 0
  JZ printed
  INC SI
  MOV AH, 0Eh ; teletype function.
  INT 10h
  JMP next_char
printed:
 
  POP SI ; re-store registers...
  POP AX ;
ENDM
 
; this macro prints a char in AL and advances
; the current cursor position:
PUTC MACRO char
  PUSH AX
  MOV AL, char
  MOV AH, 0Eh
  INT 10h
  POP AX
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 org 100h
 
 jmp start ; skip data.
 
msg1 db 13, 10, 'input numbers in this range: [-32768..32767]', 13, 10
 db 13, 10, 'enter first number: $'
 
 msg2 db 13, 10, 'enter second number: $'
 
 msg3 db 13, 10, 'the sum is: $'
 
; declaration of variable:
num dw ?
 
start:
 
; print first message
 mov dx, offset msg1
 mov ah, 9
 int 21h
 
call scan_num
 
; keep first number:
 mov num, cx
 
; print second message
 mov dx, offset msg2
 mov ah, 9
 int 21h
 
call scan_num
 
; add numbers:
 add num, cx
 jo overflow
 
; print the result:
 mov dx, offset msg3
 mov ah, 9
 int 21h
 
 mov ax, num
 call print_num
 
jmp exit
 
; process overlow error:
 overflow:
 
 printn 'we have overflow!'
 
exit:
 
; wait for any key press:
 mov ah, 0
 int 16h
 
ret ; return control to operating system.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; estas funciones son copiadas del emu8086.inc ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; gets the multi-digit SIGNED number from the keyboard,
; and stores the result in CX register:
SCAN_NUM PROC NEAR
  PUSH DX
  PUSH AX
  PUSH SI
 
  MOV CX, 0
 
  ; reset flag:
  MOV CS:make_minus, 0
 
next_digit:
 
  ; get char from keyboard
  ; into AL:
  MOV AH, 00h
  INT 16h
  ; and print it:
  MOV AH, 0Eh
  INT 10h
 
  ; check for MINUS:
  CMP AL, '-'
  JE set_minus
 
  ; check for ENTER key:
  CMP AL, 13 ; carriage return?
  JNE not_cr
  JMP stop_input
not_cr:
 
  CMP AL, 8 ; 'BACKSPACE' pressed?
  JNE backspace_checked
  MOV DX, 0 ; remove last digit by
  MOV AX, CX ; division:
  DIV CS:ten ; AX = DX:AX / 10 (DX-rem).
  MOV CX, AX
  PUTC ' ' ; clear position.
  PUTC 8 ; backspace again.
  JMP next_digit
backspace_checked:
 
  ; allow only digits:
  CMP AL, '0'
  JAE ok_AE_0
  JMP remove_not_digit
ok_AE_0:
  CMP AL, '9'
  JBE ok_digit
remove_not_digit:
  PUTC 8 ; backspace.
  PUTC ' ' ; clear last entered not digit.
  PUTC 8 ; backspace again.
  JMP next_digit ; wait for next input.
ok_digit:
 
; multiply CX by 10 (first time the result is zero)
  PUSH AX
  MOV AX, CX
  MUL CS:ten ; DX:AX = AX*10
  MOV CX, AX
  POP AX
 
; check if the number is too big
; (result should be 16 bits)
  CMP DX, 0
  JNE too_big
 
; convert from ASCII code:
  SUB AL, 30h
 
; add AL to CX:
  MOV AH, 0
  MOV DX, CX ; backup, in case the result will be too big.
  ADD CX, AX
  JC too_big2 ; jump if the number is too big.
 
  JMP next_digit
 
set_minus:
  MOV CS:make_minus, 1
  JMP next_digit
 
too_big2:
  MOV CX, DX ; restore the backuped value before add.
  MOV DX, 0 ; DX was zero before backup!
too_big:
  MOV AX, CX
  DIV CS:ten ; reverse last DX:AX = AX*10, make AX = DX:AX / 10
  MOV CX, AX
  PUTC 8 ; backspace.
  PUTC ' ' ; clear last entered digit.
  PUTC 8 ; backspace again.
  JMP next_digit ; wait for Enter/Backspace.
 
 
stop_input:
  ; check flag:
  CMP CS:make_minus, 0
  JE not_minus
  NEG CX
not_minus:
 
  POP SI
  POP AX
  POP DX
  RET
make_minus DB ? ; used as a flag.
SCAN_NUM ENDP
 
; this procedure prints number in AX,
; used with PRINT_NUM_UNS to print signed numbers:
PRINT_NUM PROC NEAR
  PUSH DX
  PUSH AX
 
  CMP AX, 0
  JNZ not_zero
 
  PUTC '0'
  JMP printed
 
not_zero:
  ; the check SIGN of AX,
  ; make absolute if it's negative:
  CMP AX, 0
  JNS positive
  NEG AX
 
  PUTC '-'
 
positive:
  CALL PRINT_NUM_UNS
printed:
  POP AX
  POP DX
  RET
PRINT_NUM ENDP
 
 
; this procedure prints out an unsigned
; number in AX (not just a single digit)
; allowed values are from 0 to 65535 (0xFFFF)
PRINT_NUM_UNS PROC NEAR
  PUSH AX
  PUSH BX
  PUSH CX
  PUSH DX
 
  ; flag to prevent printing zeros before number:
  MOV CX, 1
 
  ; (result of "/ 10000" is always less or equal to 9).
  MOV BX, 10000 ; 2710h - divider.
 
  ; AX is zero?
  CMP AX, 0
  JZ print_zero
 
begin_print:
 
 ; check divider (if zero go to end_print):
  CMP BX,0
  JZ end_print
 
  ; avoid printing zeros before number:
  CMP CX, 0
  JE calc
  ; if AX<BX then result of DIV will be zero:
  CMP AX, BX
  JB skip

calc:
  MOV CX, 0 ; set flag.
 
  MOV DX, 0
  DIV BX ; AX = DX:AX / BX (DX=remainder).
 
 ; print last digit
 ; AH is always ZERO, so it's ignored
  ADD AL, 30h ; convert to ASCII code.
  PUTC AL
 
  MOV AX, DX ; get remainder from last div.
 
skip:
  ; calculate BX=BX/10
  PUSH AX
  MOV DX, 0
  MOV AX, BX
  DIV CS:ten ; AX = DX:AX / 10 (DX=remainder).
  MOV BX, AX
  POP AX
 
  JMP begin_print
 
print_zero:
  PUTC '0'
 
end_print:
 
  POP DX
  POP CX
  POP BX
  POP AX
  RET
PRINT_NUM_UNS ENDP
 
ten DW 10 ; used as multiplier/divider by SCAN_NUM & PRINT_NUM_UNS.

Eggun
Mensajes: 8
Registrado: Mié Abr 24, 2013 10:39 pm

Re: Calculadora en Ensamblador, Sumar, Restar, Multiplicar,

Mensajepor Eggun » Lun Jul 29, 2013 7:23 am

Gracias por el código


Volver a “Distribuciones”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado