flat assembler
Message board for the users of flat assembler.
Index
> DOS > disk access counter |
Author |
|
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 |
|||
30 Apr 2006, 22:04 |
|
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 |
|||
04 May 2006, 18:18 |
|
vid 08 Sep 2006, 08:32
hmmm... i am moving this to DOS section... you know, it's more example than tool
|
|||
08 Sep 2006, 08:32 |
|
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... |
|||
08 Sep 2006, 11:44 |
|
vid 08 Sep 2006, 12:13
okay, any idea how to highlight it for those who might be interested?
|
|||
08 Sep 2006, 12:13 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.