logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog

follow us in feedly

Usando Win32 API para otimizar o I/O, parte 5

Parte Zero     Parte 1     Parte 2     Parte 3     Parte 4     Parte 5     Parte 6     Fontes do parser

Um fator muito importante na hora de melhorar o desempenho de um aplicativo é saber exatamente o que está acontecendo e o que ele está fazendo. Não podemos fazer modificações em um software sem saber se essas modificações vão trazer alguma melhora e sem saber o motivo da melhora. Lembre-se do que eu falei sobre mensuração, precisamos saber exatamente qual foi o grau de melhoria.

Hoje não vamos otimizar nada, mas vamos descobrir porque a nossa versão ficou mais rápida do que a que usa a runtime do C++. Afinal, nosso código faz exatamente a mesma coisa: ler o arquivo inteiro. Só que nós lemos da melhor forma possível (o arquivo todo de uma vez só), e acreditamos que essa não seja a forma usada pela runtime do C++.

Para descobrir como a runtime do C++ faz a leitura do arquivo, vamos usar o WinDbg. Com ele vamos saber exatamente quais parâmetros estão sendo passados para as funções da Win32 API. Como a Win32 API é o acesso mais low level que se pode ter em user mode, a runtime do C++ só pode acabar usando a Win32 API no final das contas.

A função que faz a leitura de um arquivo é a ReadFile (a ReadFileEx é usada somente para leituras assíncronas). Sabendo disso, vamos colocar um breakpoint na função ReadFile e fazer um dump dos parâmetros a cada chamada. Carregue o executável no WinDbg (veja os tutoriais de Windbg caso ache necessário), e coloque o breakpoint na função ReadFile. Depois disso, go, go, go:

0:000> bp KERNEL32!ReadFile
0:000> g
Breakpoint 0 hit
eax=002f0650 ebx=002f26b8 ecx=002f26b8 edx=002f0081 esi=00000018 edi=0042dfc0
eip=79736168 esp=0012f7f0 ebp=0012f824 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
KERNEL32!ReadFile:
79736168 55               push    ebp

Chegamos ao ReadFile, agora precisamos fazer um dump dos parâmetros. Olhando a documentação da MSDN, vemos que o primeiro parâmetro é o HANDLE do arquivo, e o terceiro é a quantidade de bytes lidos. Fazendo dump desses parâmetros conseguimos saber exatamente como a runtime do C++ está fazendo a leitura. Código primeiro, explicação depois:

0:000> * Informações do handle (primeiro parâmetro)
0:000> !handle poi(@esp+4) 4
Handle 3d4
  Name         	\Device\HarddiskVolume1\temp\test.idl
0:000> * Quantidade de bytes lidos (terceiro parâmetro)
0:000> dd @esp+0xc L1
0012f7fc  00001000

A primeira coisa que fizemos foi pegar informações sobre o HANDLE do arquivo. Usamos a extensão !handle, que com a flag 4 no final faz um dump de todas as informações do HANDLE, inclusive nome do arquivo quando cabível (pode ser um HANDLE de evento ou outra coisa...). Pegamos o primeiro parâmetro usando @esp+4 (já falei sobre posição de parâmetros na pilha x86 anteriormente) e colocamos poi() para tratá-lo como um ponteiro e pegar o apontado. Apesar do tipo ser HANDLE e não um ponteiro, HANDLE nada mais é do que um #define para void*. Depois disso usamos o dd (Dump DWORD) para ler o terceiro parâmetro - a primeira coluna é o endereço de memória lido e o L1 no final é para ler somente um DWORD, o default é ler 32 DWORDs. Note que tudo vem em hexadecimal, então 00001000 é na realidade 4096 em decimal, que na realidade é o tamanho de uma página de memória x86 (na realidade, eu já falei sobre alinhamento e paginação de memória nessa série).

Temos as informações da primeira chamada à ReadFile, mas repetir esses comandos em todas as chamadas é muito trabalhoso. Por isso vamos criar um breakpoint que execute esses comandos para fazer um log de todos os ReadFile chamados. Vamos ao comando:

0:000> bp kernel32!ReadFile "!handle poi(@esp+4) 4; dd esp+0xC L1 ; g"
0:000> g

Com esses comandos faremos o dump das informações que queremos e deixaremos o programa seguir (g). Vamos ao resultado:

0:000> g
Handle 3d4
  Name         	\Device\HarddiskVolume1\temp\test.idl
0012f7fc  00001000
Handle 3d4
  Name         	\Device\HarddiskVolume1\temp\test.idl
0012f7fc  00001000
Handle 3d4
  Name         	\Device\HarddiskVolume1\temp\test.idl
0012f7fc  00001000
Handle 3d4
  Name         	\Device\HarddiskVolume1\temp\test.idl
0012f7fc  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00000001
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00000001
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f200  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012ec04  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\Unknwn.Idl
0012e608  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\Unknwn.Idl
0012e608  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\Unknwn.Idl
0012e608  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0

  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012e00c  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00000001
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00000001
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f200  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ServProv.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\ServProv.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00000001
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00000001
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012ec04  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\MsXml.Idl
0012e608  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\MsXml.Idl
0012e608  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\MsXml.Idl
0012e608  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\MsXml.Idl
0012e608  00001000
Handle 3c4
  Name         	...\Microsoft SDK\include\MsXml.Idl
0012e608  00001000
eax=00000000 ebx=7ffdf000 ecx=00000000 edx=00000000 esi=7846ee04 edi=00000000
eip=7846ee0f esp=0012fe00 ebp=0012fec8 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
ntdll!NtTerminateProcess+0xb:
7846ee0f c20800           ret     0x8

Pronto, descobrimos que a runtime do C++ (usando getline(f, str, f.widen(EOF))) pede 4096 bytes a cada leitura. Nosso parser fica mais rápido usando Win32 API diretamente porque lemos o arquivo todo de uma vez, além de passar a flag que avisa o Windows que leremos o arquivo sequencialmente. Olhe como fica o mesmo dump feito com a versão Win32:

0:000> bp kernel32!ReadFile "!handle poi(@esp+4) 4; dd esp+0xC L1 ; g"
0:000> g
Handle 3d4
  Name         	\Device\HarddiskVolume1\temp\test.idl
0012f834  00002cfd
Handle 3d8
  Name         	...\Microsoft SDK\include\OAIdl.Idl
0012f1d8  0000ecf9
Handle 3c8
  Name         	...\Microsoft SDK\include\ObjIdl.Idl
0012eb7c  00012200
Handle 3c4
  Name         	...\Microsoft SDK\include\Unknwn.Idl
0012e520  000013fb
Handle 3c0
  Name         	...\Microsoft SDK\include\WTypes.Idl
0012dec4  00009ea7
Handle 3d8
  Name         	...\Microsoft SDK\include\OCIdl.Idl
0012f1d8  0000a35b
Handle 3c8
  Name         	...\Microsoft SDK\include\OleIdl.Idl
0012eb7c  00006d48
Handle 3c8
  Name         	...\Microsoft SDK\include\ServProv.Idl
0012eb7c  00000e93
Handle 3c8
  Name         	...\Microsoft SDK\include\UrlMon.Idl
0012eb7c  0001cd2f
Handle 3c4
  Name         	...\Microsoft SDK\include\MsXml.Idl
0012e520  00003048
eax=00000000 ebx=7ffdf000 ecx=00000000 edx=00000000 esi=7846ee04 edi=00000000
eip=7846ee0f esp=0012fe00 ebp=0012fec8 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
ntdll!NtTerminateProcess+0xb:
7846ee0f c20800           ret     0x8

Agora temos um log bem menor porque só fazemos uma chamada à ReadFile por arquivo. Agora sabemos exatamente o motivo pelo qual nosso I/O é mais rápido.


Em 08/09/2005 14:27, por Rodrigo Strauss


  
 
 
Comentários
Victor | website | em 14/09/2005 | #
Pq agora pra optimizar vc nao usa syscall mesmo pura ?
tipo:
NtCreateFile:
mov eax, 0x0000001A
lea edx, [esp+04]
int 0x2E
ret 0x2C

NtReadFile:
....

etc etc etc ?


Claro que teriamos que escrever as funcoes de acordo com o build do OS (os version, patch level, language) mas faz ai pelo menos 1 vez pra vermos a diferenca :-)

Abraços!
Rodrigo Strauss | website | em 15/09/2005 | #
Nesse caso eu acho que não ajuda muito. Como é feita somente uma leitura por arquivo vamos economizar isso:

KERNEL32!ReadFile:
79736168 55 push ebp
79736169 8bec mov ebp,esp
7973616b 6aff push 0xff
7973616d 68801e7279 push 0x79721e80
79736172 68441f7779 push 0x79771f44
79736177 64a100000000 mov eax,fs:[00000000]
7973617d 50 push eax
7973617e 64892500000000 mov fs:[00000000],esp
79736185 51 push ecx
79736186 51 push ecx
79736187 83ec24 sub esp,0x24
7973618a 53 push ebx
7973618b 56 push esi
7973618c 57 push edi
7973618d 8965e8 mov [ebp-0x18],esp
79736190 33db xor ebx,ebx
79736192 8b4d14 mov ecx,[ebp+0x14]
79736195 3bcb cmp ecx,ebx
79736197 7402 jz KERNEL32!ReadFile+0x33 (7973619b)
79736199 8919 mov [ecx],ebx
7973619b 64a118000000 mov eax,fs:[00000018]
797361a1 8b4030 mov eax,[eax+0x30]
797361a4 8b7d08 mov edi,[ebp+0x8]
797361a7 83fff4 cmp edi,0xfffffff4
797361aa 741a jz KERNEL32!ReadFile+0x5e (797361c6)
797361ac 83fff5 cmp edi,0xfffffff5
797361af 740d jz KERNEL32!ReadFile+0x56 (797361be)
797361b1 83fff6 cmp edi,0xfffffff6
797361b4 7516 jnz KERNEL32!ReadFile+0x64 (797361cc)
797361b6 8b4010 mov eax,[eax+0x10]
797361b9 8b7818 mov edi,[eax+0x18]
797361bc eb0e jmp KERNEL32!ReadFile+0x64 (797361cc)
797361be 8b4010 mov eax,[eax+0x10]
797361c1 8b781c mov edi,[eax+0x1c]
797361c4 eb06 jmp KERNEL32!ReadFile+0x64 (797361cc)
797361c6 8b4010 mov eax,[eax+0x10]
797361c9 8b7820 mov edi,[eax+0x20]
797361cc 8bc7 mov eax,edi
797361ce 2503000010 and eax,0x10000003
797361d3 83f803 cmp eax,0x3
797361d6 756f jnz KERNEL32!ReadFile+0xdf (79736247)
797361d8 ff7518 push dword ptr [ebp+0x18]
797361db 51 push ecx
797361dc ff7510 push dword ptr [ebp+0x10]
797361df ff750c push dword ptr [ebp+0xc]
797361e2 57 push edi
797361e3 e85d450200 call KERNEL32!ReadConsoleA (7975a745)
797361e8 85c0 test eax,eax
797361ea 0f844d010000 je KERNEL32!ReadFile+0x1d5 (7973633d)
797361f0 33f6 xor esi,esi
797361f2 8d45d4 lea eax,[ebp-0x2c]
797361f5 50 push eax
797361f6 57 push edi
797361f7 e8ac610200 call KERNEL32!GetConsoleMode (7975c3a8)
797361fc 85c0 test eax,eax
797361fe 7503 jnz KERNEL32!ReadFile+0x9b (79736203)
79736200 895dd4 mov [ebp-0x2c],ebx
79736203 f645d401 test byte ptr [ebp-0x2c],0x1
79736207 7430 jz KERNEL32!ReadFile+0xd1 (79736239)
79736209 895dfc mov [ebp-0x4],ebx
7973620c 8b450c mov eax,[ebp+0xc]
7973620f 80381a cmp byte ptr [eax],0x1a
79736212 7505 jnz KERNEL32!ReadFile+0xb1 (79736219)
79736214 8b4514 mov eax,[ebp+0x14]
79736217 8918 mov [eax],ebx
79736219 834dfcff or dword ptr [ebp-0x4],0xffffffff
7973621d eb1a jmp KERNEL32!ReadFile+0xd1 (79736239)
7973621f 8b45ec mov eax,[ebp-0x14]
79736222 8b00 mov eax,[eax]
79736224 8b00 mov eax,[eax]
79736226 8945c8 mov [ebp-0x38],eax
79736229 6a01 push 0x1
7973622b 58 pop eax
7973622c c3 ret
7973622d 8b65e8 mov esp,[ebp-0x18]
79736230 8b75c8 mov esi,[ebp-0x38]
79736233 834dfcff or dword ptr [ebp-0x4],0xffffffff
79736237 33db xor ebx,ebx
79736239 3bf3 cmp esi,ebx
7973623b 0f8dd9000000 jnl KERNEL32!ReadFile+0x1b2 (7973631a)
79736241 56 push esi
79736242 e9f1000000 jmp KERNEL32!ReadFile+0x1d0 (79736338)
79736247 8b7518 mov esi,[ebp+0x18]
7973624a 3bf3 cmp esi,ebx
7973624c 0f8481000000 je KERNEL32!ReadFile+0x16b (797362d3)
79736252 bb03010000 mov ebx,0x103
79736257 891e mov [esi],ebx
79736259 8b4608 mov eax,[esi+0x8]
7973625c 8945cc mov [ebp-0x34],eax
7973625f 8b460c mov eax,[esi+0xc]
79736262 8945d0 mov [ebp-0x30],eax
79736265 8b4610 mov eax,[esi+0x10]
79736268 6a00 push 0x0
7973626a 8d4dcc lea ecx,[ebp-0x34]
7973626d 51 push ecx
7973626e ff7510 push dword ptr [ebp+0x10]
79736271 ff750c push dword ptr [ebp+0xc]
79736274 56 push esi
79736275 8bc8 mov ecx,eax
79736277 80e101 and cl,0x1
7973627a f6d9 neg cl
7973627c 1bc9 sbb ecx,ecx
7973627e f7d1 not ecx
79736280 23ce and ecx,esi
79736282 51 push ecx
79736283 6a00 push 0x0
79736285 50 push eax
79736286 57 push edi
79736287 ff15a0117279 call dword ptr [KERNEL32!_imp__NtReadFile (797211a0)]

Que nem é tanta coisa assim. Até pq ele não roda esse código inteiro, um jump manda ele pro NtReadFile sem muita demora. Além de ser bem joselito :-)

Se fosse um programa que usasse I/O mais espalhado e e vários lugares aí valeria a pena e faria diferença.
Algo a dizer?
Nome:


Site:


E-mail:


Escreva o número vinte e seis:


 Não mostre meu e-mail no site, não serve pra nada mesmo...

Comentário





Os comentários devem ser sobre assuntos relativos ao post, eu provavelmente apagarei comentários totalmente offtopic. Se quiser me enviar uma mensagem, use o formulário de contato. E não esqueça: isso é um site pessoal e eu me reservo o direito de apagar qualquer comentário ofensivo ou inapropriado.
rebarba rebarba
  ::::