programming-examples/assembly/Show Memory.asm

283 lines
12 KiB
NASM
Raw Normal View History

2019-11-15 12:59:38 +01:00
kbd equ 16h ;keyboard irq
msdos equ 21h ;MSDOS irq
reset equ 0dh ;disk reset
dfopen equ 0fh ;open disk file
dfclose equ 10h ;close disk file
searchf equ 11h ;search first
searchn equ 12h ;search next
seqread equ 14h ;sequential disk read
seqwrite equ 15h ; " " write
setdta equ 1ah ;set disk transfer area address
createf equ 3ch ;create file with handle
openf equ 3dh ;open file with handle
closef equ 3eh ;close file with handle
readf equ 3fh ;read from file with handle
writef equ 40h ;write to file with handle
setfp equ 42h ;set file pointer
allocmem equ 48h ;allocate memory
freemem equ 49h ;free memory
changebs equ 4ah ;change block size
findfirst equ 4eh ;find first file
exit equ 4c00h ;msdos exit
[BITS 16] ;NASM stuff
[ORG 0x100]
s1:
mov ax,cs ;get code segment
mov ds,ax ;use it now
mov [comseg],ds ;save it there
mov si,0080h ;DOS command line page 0
lodsb ;load size of command line
cmp al,0 ;anything on command line ?
jbe usage ;noo, show usage
cbw ;extend AL to AX
xchg bx,ax ;swap size to bx for indexing
mov byte [bx+si],0 ;null terminate command line
call parse ;parse command line
jmp main ;go on with main
usage: mov bx,utext ;pointer usage text
jmp errout ;skip this
main:
mov si,inbuff ;check for valid HEX input
mov bx,errt1 ;proper text
ishex: lodsb ;get the char
cmp al,'0'
jb errout
and al,0dfh ;force UPPERCASE
cmp al,'F' ;>F ?
ja errout ;yeahh, dump this
loop ishex
call hexbin ;make hex bin
;start address now in EDX
mov ax,dx ;get low word (segment)
mov es,ax ;start segment
shr edx,16 ;shift in offset
mov di,dx ;start offset
dopage:
push es ;save registers
push di
push ds
push si
mov ax,es
mov ds,ax ;make ds=es
mov si,di ;and si=di
call showpage ;show it
pop si ;restore registers
pop ds
pop di
pop es
add di,512 ;adjust memory position
;xor ah,ah ;wait for ANY key
;int kbd
mov bx,text ;show message
call write
mov ah,0 ;wanna see next screen ?
int kbd ;chek out keyboard buffer
and al,0DFh ;force UPPER CASE
cmp al,"Q" ;wanna quit ?
je quit ;yeahh
jmp dopage
errout:
call write
quit:
mov ax,exit
int msdos
;***********************************************************
;* Convert ascii hex to 32 bit binary
;* Input = command line buffer, output EDX
;***********************************************************
hexbin:
mov si,inbuff ;pointer command line buffer
xor edx,edx ;clear binary output
aschexbin:
lodsb
cmp al,'0' ;< 0
jb notasc ;yes invalid character
cmp al,'9' ;<= 9
jbe astrip ;yes, strip high 4 bits
and al,05fh ;force upper case
cmp al,'A' ;< ascii A
jb notasc ;yes, invalid character
cmp al,'F' ;> ascii F
ja notasc ;yes, invalid character
add al,9 ;ok, add 9 for strip
astrip:
and al,0fh ;strip high 4 bits
mov cx,4 ;set shift count
shl edx,cl ;rotate EDX 4 bits
xor ah,ah ;zero out AH
cbw
add edx,eax ;add digit to value
jmp aschexbin ;continue
notasc: ret
;*********************************************************************
;* Format and show the stuff in a "sector"
;* Input SI
;*********************************************************************
showpage:
mov cx,32 ;32*16=512
arow: push cx
mov di,outline ;output buffer
mov cx,16 ;process 16 bytes
hexrow: push cx
lodsb ;load al with byte
mov dl,al ;get value
mov cx,2 ;2 nibbles
chexb: push cx ;save that
mov cl,4 ;4 bits
rol dl,cl ;rotate source left
mov al,dl ;move digit into AL
and al,15 ;clear high nibble
daa ;adjust AL if A through F
add al,240 ;bump the carry
adc al,40h ;convert HEX to ASCII
stosb ;copy to buffer
pop cx ;get digit counter
loop chexb ;next digit
mov al,32 ;copy a SPACE
stosb
pop cx ;restore loop counter
loop hexrow ;loop on
mov al,32 ;copy 2 spaces
stosb
stosb
sub si,16 ;adjust source back
mov cx,16 ;copy ASCII bytes
cccp: lodsb
cmp al,32 ;< SPACE ?
jb noa ;yeahh, skip it
stosb ;no, store in buffer
jmp next
noa: mov al,'.'
stosb
next loop cccp
mov al,13
stosb
mov al,10
stosb
mov al,0 ;null terminate line
stosb
mov bx,outline ;show the line
call write
pop cx
cmp cx,17
jne nopause
push ds
mov ax,cs
mov ds,ax
mov bx,text1
call write
pop ds
xor ah,ah
int kbd
nopause:
loop arow ;next 16 bytes
ret
;************************************************************************'
;* Convert bin WORD to HEX ascii. Input DX. Result in Numbuff *
;************************************************************************
binhex: pusha
mov di,numbuff ;destination buffer
mov dx,[count] ;binary number
mov cx,4 ;four nibbles
convhex:
push cx ;save counter
mov cl, 4 ;4 bits
rol dx, cl ;rotate source left
mov al, dl ;move digit into AL
and al, 15 ;clear high nibble
daa ;adjust AL if A through F
add al, 240 ;bump the carry
adc al, 40h ;convert HEX to ASCII
stosb ;copy to buffer
pop cx ;get digit counter
loop convhex ;next digit
mov al,32 ;copy a space
stosb
mov al,0 ;null terminate
stosb
popa
ret
;*************************************************************************
;* Writes out the NULL terminated text supplied in BX. *
;* OR writes out data,BX and size,CX if called at lwrite. *
;*************************************************************************
write: pusha
mov si,bx ;copy to SI
mov cx,0 ;clear count
wloop: lodsb ;load AL with SI
cmp al,0 ;end of line ?
je lwrite ;yeahh
inc cx ;no, incrase byte count
jmp wloop ;test next byte
lwrite: mov dx,bx ;text address in DX
mov bx,1 ;filehandle standard output = 1
mov ah,writef ;MS-DOS writefile with handle is 040
int msdos ;write buffer to standard output
popa
ret ;done
;*************************************************************************
;* My kind of command line parsing. It just checks if there<72>s
;* any blankspaces between the options. The parameters ends up
;* in the inbuff separated by 0:s, binary zeroes.
;*************************************************************************
parse:
mov di,inbuff ;our buffer
ifspc: cmp byte [si],32 ;leading space ?
jne nospc ;noo
inc si ;yeahh, dump that
jmp ifspc ;check next
nospc: mov cx,1 ;were here, so we got one arg
copy1: lodsb ;load byte SI to AL
cmp al,0 ;0 ?(end of line)
je done ;yeahh
cmp al,32 ;SPACE ?
je cop2 ;yeah
stosb ;noo, move AL to DI, incrase DI
jmp copy1 ;go on
cop2: mov byte [di],0 ;null terminate
add cx,1
inc di ;dump that byte(SPACE)
jmp copy1 ;back
done: mov byte [di],0 ;null terminate
ret ;return
;*************************** DATA STUFF **********************************
XMS_SEGMENT dw 0
XMS_OFFSET dw 0
inbuff times 64 dw 0 ;128 byte command line buffer
outline times 40 dw 0 ;buffer output line
numbuff times 7 dw 0 ;word ascii number buffer
comseg dw 0
count dw 0
bcount dw 0
acount dw 0
;outbuff times 512 db 0
utext db 'WWW',13,10
db 'Usage: Showmem [start address].',13,10
db 'Start address = Hexadecimal.',13,10,0
text: db 13,10,'Q = Quit. Any key = Next page.',13,10,0
text1: db 13,10,'Any Key = Next 256 Bytes.',13,10,0
errt1: db 'That address is not hexadecimal.',13,10,0
s2:
END