; smá tilraun af þessu forriti í assembler
; já ég hafði lítið að gera!
#make_COM#
ORG 100h
; 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
; print a welcome message:
LEA SI, msg1
CALL PRINT_STRING
; get string to DS:DI
LEA DI, buffer ; buffer offset.
MOV DX, 81 ; buffer size.
CALL get_string
PUTC 13
PUTC 10 ; next line.
;count the A/a's see COUNT_A
MOV SI, DI
CALL COUNT_A
;print out the message
LEA SI, msg3
CALL PRINT_STRING
;print out the number we countet
MOV AX,BX
CALL PRINT_NUM_UNS
PUTC 13
PUTC 10 ; next line.
;print message 2
LEA SI, msg2
CALL PRINT_STRING
;print the string entered reversed
LEA DI, buffer
MOV SI, DI
CALL REV_PRINT_STRING
PUTC 13
PUTC 10 ; next line.
RET
buffer DB ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’
revbuffer DB ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’
msg1 DB ‘Enter a string: ’, 0
msg2 DB ‘String reversed: ’, 0
msg3 DB ‘Number of A/a: ’, 0
GET_STRING PROC NEAR
PUSH AX
PUSH CX
PUSH DI
PUSH DX
MOV CX, 0 ; char counter.
CMP DX, 1 ; buffer too small?
JBE empty_buffer ;
DEC DX ; reserve space for last zero.
;============================
; Eternal loop to get
; and processes key presses:
wait_for_key:
MOV AH, 0 ; get pressed key.
INT 16h
CMP AL, 13 ; ‘RETURN’ pressed?
JZ exit
CMP AL, 8 ; ‘BACKSPACE’ pressed?
JNE add_to_buffer
JCXZ wait_for_key ; nothing to remove!
DEC CX
DEC DI
PUTC 8 ; backspace.
PUTC ‘ ’ ; clear position.
PUTC 8 ; backspace again.
JMP wait_for_key
add_to_buffer:
CMP CX, DX ; buffer is full?
JAE wait_for_key ; if so wait for ‘BACKSPACE’ or ‘RETURN’…
MOV [DI], AL
INC DI
INC CX
; print the key:
MOV AH, 0Eh
INT 10h
JMP wait_for_key
;============================
exit:
; terminate by null:
MOV [DI], 0
empty_buffer:
POP DX
POP DI
POP CX
POP AX
RET
GET_STRING ENDP
REV_PRINT_STRING PROC NEAR
PUSH AX ; store registers…
PUSH SI ;
MOV BX,1
REV_next_char:
MOV AL, [SI]
CMP AL, 0
JZ REV_PRINT
INC SI
INC BX
JMP REV_next_char
REV_PRINT:
MOV AL, [SI]
CMP BX, 0
JZ REV_DONE
DEC SI
DEC BX
MOV AH, 0Eh ; teletype function.
INT 10h
JMP REV_PRINT
REV_DONE:
POP SI ; re-store registers…
POP AX ;
RET
REV_PRINT_STRING ENDP
PRINT_STRING PROC NEAR
PUSH AX ; store registers…
PUSH SI ;
next_char:
MOV AL, [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 ;
RET
PRINT_STRING ENDP
COUNT_A PROC NEAR
PUSH AX ; store registers…
PUSH SI ;
next_char_COUNT:
MOV AL, [SI]
CMP AL, 0
JZ E_COUNT
CMP AL, 65
JZ ct
CMP AL, 97
JZ ct
INC SI
;MOV AH, 0Eh ; teletype function.
;INT 10h
JMP next_char_COUNT
ct:
INC BX
INC SI
JMP next_char_COUNT
E_COUNT:
POP SI ; re-store registers…
POP AX ;
RET
COUNT_A ENDP
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