flat assembler
Message board for the users of flat assembler.

Index > DOS > disk access counter

Author
Thread Post new topic Reply to topic
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 30 Apr 2006, 22:04
Yesterday I made a DOS app which hooks the int21 to count the number of read, write and seeks of another DOS app passed as command line parameter. I made it to test the algorithms we use at Introduction to Data Bases.

It's in spanish but it's no so hard to understand anyway.

stackNecesario is used to set the amount of stack memory required (64 bytes in this case). I don't know if that is a reliable size, I'm still waiting reply to the post http://board.flatassembler.net/topic.php?t=5189

Well, hope that this can be useful to somebody

Regards

Code:
; Ensambla con FASM http://www.flatassembler.net/
; NOTA: Requiere como mínimo un 386

struc Vector
{
  .offset dw ?
  .seg    dw ?
}

struc Contadores
{
  .funcion14 dd ?
  .funcion15 dd ?

  .funcion21 dd ?
  .funcion22 dd ?

  .funcion27 dd ?
  .funcion28 dd ?

  .funcion3F dd ?
  .funcion40 dd ?

  .funcion42 dd ?
}

virtual at 0
 Vector Vector ; Para que me queden definidos los offsets de los campos así los uso en cualquier parte
end virtual

virtual at 0
 Contadores Contadores ; Para que me queden definidos los offsets de los campos así los uso en cualquier parte
end virtual

offsetInt21 equ $21 * 4
stackNecesario = 64

org $100
; Libero memoria para así dejarsela al programa a analizar
  cmp     sp, memNecesaria
  jb      .faltaMemoria

  mov     ah, $4A
  mov     bx, (memNecesaria + $0F) / $10
  mov     sp, (memNecesaria + $0F) / $10 * $10
  int     $21

  push    0
  pop     es

; Salvo el vector original
  mov     eax, [es:offsetInt21]
  mov     [vectorInt21], eax

; Cargo el nuevo vector
  mov     [es:offsetInt21 + Vector.offset], int21Handler
  mov     [es:offsetInt21 + Vector.seg], cs

; Ejecuto el programa a analizar
  mov     [regSP], sp
  mov     si, $0080
  int     $2E

; La int anterior destruye todos los registros excepto CS e IP, a restaurar entonces...
  mov     ax, cs
  mov     ss, ax
  mov     ds, ax
  mov     sp, [regSP]

; Restauro el vector original
  push    0
  pop     es
  mov     eax, [vectorInt21]
  mov     [es:offsetInt21], eax

; Imprimo los contadores
  mov     bx, contadores

  mov     dx, msgFuncion14
  mov     eax, [bx + Contadores.funcion14]
  call    imprimirContador

  mov     dx, msgFuncion15
  mov     eax, [bx + Contadores.funcion15]
  call    imprimirContador

  mov     dx, msgFuncion21
  mov     eax, [bx + Contadores.funcion21]
  call    imprimirContador

  mov     dx, msgFuncion22
  mov     eax, [bx + Contadores.funcion22]
  call    imprimirContador

  mov     dx, msgFuncion27
  mov     eax, [bx + Contadores.funcion27]
  call    imprimirContador

  mov     dx, msgFuncion28
  mov     eax, [bx + Contadores.funcion28]
  call    imprimirContador

  mov     dx, msgFuncion3F
  mov     eax, [bx + Contadores.funcion3F]
  call    imprimirContador

  mov     dx, msgFuncion40
  mov     eax, [bx + Contadores.funcion40]
  call    imprimirContador

  mov     dx, msgFuncion42
  mov     eax, [bx + Contadores.funcion42]
  call    imprimirContador

; Sale del programa
  int     $20

.faltaMemoria:
  mov     ah, 9
  mov     dx, msgFaltaMemoria
  int     $21

  int     $20

imprimirContador: ; DX = Mensaje EAX = contador
  push    eax
  mov     ah, 9
  int     21h
  pop     eax

  push    bx
  mov     bx, sp
  sub     sp, 14

  dec     bx
  mov     byte [bx], '$'
  dec     bx
  mov     byte [bx], 10
  dec     bx
  mov     byte [bx], 13

  mov     ecx, 10

@@:
  dec     bx
  xor     edx, edx
  div     ecx
  add     dl, '0'
  mov     [bx], dl

  test    eax, eax
  jnz     @b

  mov     ah, 9
  mov     dx, bx
  int     $21

  add     sp, 14
  pop     bx
  ret

int21Handler:
  pushf         ; Por las dudas haya servicios que dependan de valores de los flags
  push    ds
  push    bx

  mov     bx, contadores
  push    cs
  pop     ds


; Int 21/AH=14h - DOS 1+ - SEQUENTIAL READ FROM FCB FILE
  cmp     ah, $14
  jne     @f

  inc     [bx + Contadores.funcion14]
  jmp     .salir

; Int 21/AH=15h - DOS 1+ - SEQUENTIAL WRITE TO FCB FILE
@@:
  cmp     ah, $15
  jne     @f

  inc     [bx + Contadores.funcion15]
  jmp     .salir

; Int 21/AH=21h - DOS 1+ - READ RANDOM RECORD FROM FCB FILE
@@:
  cmp     ah, $21
  jne     @f

  inc     [bx + Contadores.funcion21]
  jmp     .salir

; Int 21/AH=22h - DOS 1+ - WRITE RANDOM RECORD TO FCB FILE
@@:
  cmp     ah, $22
  jne     @f

  inc     [bx + Contadores.funcion22]
  jmp     .salir

; Int 21/AH=27h - DOS 1+ - RANDOM BLOCK READ FROM FCB FILE
@@:
  cmp     ah, $27
  jne     @f

  inc     [bx + Contadores.funcion27]
  jmp     .salir

; Int 21/AH=28h - DOS 1+ - RANDOM BLOCK WRITE TO FCB FILE
@@:
  cmp     ah, $28
  jne     @f

  inc     [bx + Contadores.funcion28]
  jmp     .salir

; Int 21/AH=3Fh - DOS 2+ - READ - READ FROM FILE OR DEVICE
@@:
  cmp     ah, $3F
  jne     @f

  inc     [bx + Contadores.funcion3F]
  jmp     .salir

; Int 21/AH=40h - DOS 2+ - WRITE - WRITE TO FILE OR DEVICE
@@:
  cmp     ah, $40
  jne     @f

  inc     [bx + Contadores.funcion40]
  jmp     .salir

; Int 21/AH=42h - DOS 2+ - LSEEK - SET CURRENT FILE POSITION
@@:
  cmp     ah, $42
  jne     .salir

  inc     [bx + Contadores.funcion42]

.salir:
  pop     bx
  pop     ds
  popf

; Como Intel reservó los prefijos CS y DS para que hagan algo distinto que segment override en las instrucciones
; de control de flujo me veo obligado a usar lo de abajo en vez de hacer simplemente jmp dword [cs:vectorInt21].
; Por ejemplo en los Pentium IV ya se usan esos prefijos reservados como branch hints en las instrucciones
; de salto condicional. Si bien un Pentium IV acepta jmp dword [cs:vectorInt21] un Pentium VIII tal vez no lo haga...
  push    dword [cs:vectorInt21]
  retf

; #### DATOS INICIALIZADOS
contadores  Contadores ; Se inicializa automáticamente en 0 gracias a que hay más datos abajo

msgFaltaMemoria db 'Memoria insuficiente', 13, 10, '$'

msgFuncion14 db 'Llamadas a Int 21/14h - DOS 1+ - SEQUENTIAL READ FROM FCB FILE: $'
msgFuncion15 db 'Llamadas a Int 21/15h - DOS 1+ - SEQUENTIAL WRITE TO FCB FILE: $'

msgFuncion21 db 'Llamadas a Int 21/21h - DOS 1+ - READ RANDOM RECORD FROM FCB FILE: $'
msgFuncion22 db 'Llamadas a Int 21/22h - DOS 1+ - WRITE RANDOM RECORD TO FCB FILE: $'

msgFuncion27 db 'Llamadas a Int 21/27h - DOS 1+ - RANDOM BLOCK READ FROM FCB FILE: $'
msgFuncion28 db 'Llamadas a Int 21/28h - DOS 1+ - RANDOM BLOCK WRITE TO FCB FILE: $'

msgFuncion3F db 'Llamadas a Int 21/3Fh - DOS 2+ - READ - READ FROM FILE OR DEVICE: $'
msgFuncion40 db 'Llamadas a Int 21/40h - DOS 2+ - WRITE - WRITE TO FILE OR DEVICE: $'

msgFuncion42 db 'Llamadas a Int 21/42h - DOS 2+ - LSEEK - SET CURRENT FILE POSITION: $'

; #### DATOS NO INICIALIZADOS
vectorInt21 Vector
regSP       dw          ?


; #### ESTO TIENE QUE ESTAR SIEMPRE AL FINAL DEL FUENTE
memNecesaria = $ + stackNecesario    
Post 30 Apr 2006, 22:04
View user's profile Send private message Reply with quote
Octavio



Joined: 21 Jun 2003
Posts: 366
Location: Spain
Octavio 04 May 2006, 13:55
64 bytes is a small stack ,perhaps it will work or not depending of Dos version.But if you want to save space, the interrupt routine can use the stack of the interrupted program that usually is big enought.
Post 04 May 2006, 13:55
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 04 May 2006, 18:18
Octavio, the interrupt handler uses the interrupted program's stack already I need stack only for the part that installs and removes the handler, loads the program to test and prints the counters. Setting the variable stackNecesario with values below than 42 the behavior is unpredictable, but with values above or iqual to 42 seems to work fine.

Cas told me in the other thread that a 256 stack could be safe, but maybe less can be too. Anyway 256 bytes it's not so terrible so I will use that amount of stack memory.

Regards
Post 04 May 2006, 18:18
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 08 Sep 2006, 08:32
hmmm... i am moving this to DOS section... you know, it's more example than tool
Post 08 Sep 2006, 08:32
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 08 Sep 2006, 11:44
It can be used to measure DOS database engines efficiency in terms of disk accesses (very important thing on this subject), doesn't it qualify as a tool?

Well, it's in spanish and abandoned anyway...
Post 08 Sep 2006, 11:44
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 08 Sep 2006, 12:13
okay, any idea how to highlight it for those who might be interested?
Post 08 Sep 2006, 12:13
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.