Page 1 sur 1

Comparaison entre trois listing, comment bien analyser ?

Publié : mer. 13/juil./2011 17:22
par Syntax.error
Bonjour,

Bien que je n'y connaisse -à peu de choses prés- rien, l'ASM m'a toujours beaucoup fasciné.
Pour me changer les idées -et m'éclaircir les idées- j'ai voulu aujourd'hui comparer des listings. ( Décompilés via OllyDbg [ et je ne suis pas certain que cette démarche soit la meilleure ] )

J'ai donc voulu commencer par vérifier si une multiplication du type ( A*-1 ) était directement traduite par le compilateur comme une inversion.

Je compile donc un code du type :

Code : Tout sélectionner

A=489
A*-1
Résultat dans Ollydbg :

Code : Tout sélectionner

MOV DWORD PTR DS:[4030E4],1E9
MOV EBX,DWORD PTR DS:[4030E4]
IMUL EBX,EBX,-1
MOV DWORD PTR DS:[4030E4],EBX
J'en conclus qu'il serait plus judicieux -bien que trivial- d'utiliser l'opérateur NOT, afin de réaliser cette opération ( je l'utilise fréquemment dans un programme qui m’intéresse ).
J'écris donc :

Code : Tout sélectionner

A=489
A=~A
Et obtiens :

Code : Tout sélectionner

MOV DWORD PTR DS:[4030E4],1E9
MOV EBX,DWORD PTR DS:[4030E4]
NOT EBX
MOV DWORD PTR DS:[4030E4],EBX
Théoriquement ( si j'ai bien compris ), ce listing nécessitera moins de cycles. Mais à cette étape là, l'histoire des MOV m'interpelle.
J'ignore quelle est l'incidence d'un tel "transfert", ainsi que j'avoue ne pas avoir -beaucoup- cherché.. Mais j'imagine qu'il est dût à ce ( A=~A ), où je demanderai donc l'allocation d'une "variable" temporaire (EBX).

J'ai donc cherché à savoir si il était possible de s'épargner cette instruction, en utilisant l'assembleur en ligne.

J'écris donc :

Code : Tout sélectionner

A = 489
!NOT dword[v_A]
Et obtiens :

Code : Tout sélectionner

MOV DWORD PTR DS:[4030E4],1E9
NOT DWORD PTR DS:[4030E4]

J'en suis maintenant à me poser cette question :

Vaudrait-il le coups d'utiliser l'instruction !NOT dword[v_A] dans un macro du type inverse(a) ? ( Même si ce gain est dérisoire, c'est vraiment pour comprendre )
Question corollaire : cette histoire de MOV "" "" "",EBX est elle, à force, dans un programme, une perte inutile de cycle ? :o


En vous remerciant,
S.

Re: Comparaison entre trois listing, comment bien analyser ?

Publié : mer. 13/juil./2011 18:19
par Backup
je vais repondre a une partie de ta question

utilise plutot EPB (mon editeur)
pour sortir tes prg en assembleurs

Purebasic sait generer de l'assembleur par le compilateur ...
(ce que EPB (mon editeur) sait demander a Purebasic)

ton code

Code : Tout sélectionner

A=489
A*-1
complet sort comme ça en assembleur Fasm

Code : Tout sélectionner

; 
; PureBasic 4.51 (Windows - x86) generated code
; 
; (c) 2010 Fantaisie Software
; 
; The header must remain intact for Re-Assembly
; 
; :System
; KERNEL32
; :Import
; 
format MS COFF
; 
extrn _ExitProcess@4
extrn _GetModuleHandleA@4
extrn _HeapCreate@12
extrn _HeapDestroy@4
; 
extrn _memset
public _PB_Instance
public _PB_ExecutableType
public _PB_MemoryBase
public PB_Instance
public PB_MemoryBase
public _PB_EndFunctions

macro pb_public symbol
{
  public  _#symbol
  public symbol
_#symbol:
symbol:
}

macro    pb_align value { rb (value-1) - ($-_PB_DataSection + value-1) mod value }
macro pb_bssalign value { rb (value-1) - ($-_PB_BSSSection  + value-1) mod value }
public PureBasicStart
; 
section '.code' code readable executable align 8
; 
; 
PureBasicStart:
; 
  PUSH   dword I_BSSEnd-I_BSSStart
  PUSH   dword 0
  PUSH   dword I_BSSStart
  CALL  _memset
  ADD    esp,12
  PUSH   dword 0
  CALL  _GetModuleHandleA@4
  MOV    [_PB_Instance],eax
  PUSH   dword 0
  PUSH   dword 4096
  PUSH   dword 0
  CALL  _HeapCreate@12
  MOV    [PB_MemoryBase],eax
; 
; A=489
  MOV    dword [v_A],489
; A*-1
  MOV    ebx,dword [v_A]
  IMUL   ebx,-1
  MOV    dword [v_A],ebx
; 
; 
_PB_EOP_NoValue:
  PUSH   dword 0
_PB_EOP:
  CALL  _PB_EndFunctions
  PUSH   dword [PB_MemoryBase]
  CALL  _HeapDestroy@4
  CALL  _ExitProcess@4
_PB_EndFunctions:
  RET
; 
; 
section '.data' data readable writeable
; 
_PB_DataSection:
pb_public PB_DEBUGGER_LineNumber
  dd     -1
pb_public PB_DEBUGGER_IncludedFiles
  dd     0
pb_public PB_DEBUGGER_FileName
  db     0
_PB_ExecutableType: dd 0
align 4
align 4
s_s:
  dd     0
  dd     -1
align 4
; 
section '.bss' readable writeable
_PB_BSSSection:
align 4
; 
I_BSSStart:
_PB_MemoryBase:
PB_MemoryBase: rd 1
_PB_Instance:
PB_Instance: rd 1
; 
align 4
PB_DataPointer rd 1
v_A rd 1
align 4
align 4
align 4
align 4
I_BSSEnd:
section '.data' data readable writeable
SYS_EndDataSection:


la partie qui t’intéresse se trouve ici :

Code : Tout sélectionner

; A=489
  MOV    dword [v_A],489
; A*-1
  MOV    ebx,dword [v_A]
  IMUL   ebx,-1
  MOV    dword [v_A],ebx
; 


elle te semblera peut etre plus comprehensible :)

ps: EPB n'est pas telechargeable pour le moment, je vais sortir une mise a jour.. :)

Re: Comparaison entre trois listing, comment bien analyser ?

Publié : jeu. 14/juil./2011 11:08
par djes
+1 avec Dobro ; sinon tu peux utiliser pureasm d'Erix14, super pratique !
http://www.rx14.info/public/index.php?a=PureASM

Pour répondre à tes questions, le code de PB, bien que rapide, n'est pas très optimisé. Nous en parlons de temps en temps ; le pire étant l'appel de procédures, et ça me fait hurler quand je vois des gens parler d'optimisations et qui font des appels de procédures à la pelle 8O

Le problème est qu'améliorer le code produit demanderait un travail considérable, et n'atteindrait jamais ce que peut faire un compilateur comme GCC, modelé depuis des années par des passionnés d'optim. Encore une fois, c'est une question de moyens humains. D'autant que PB est multi-plateformes, et à vocation à le rester. Heureusement, d'autres solutions sont apparemment testées par l'équipe, il y a eu quelques posts récemment là dessus ;)

Re: Comparaison entre trois listing, comment bien analyser ?

Publié : jeu. 14/juil./2011 16:38
par Syntax.error
Bonjour,

Je vous remercie pour ces réponses.
Je vais tester ces outils et voir celui qui se fait le plus facilement à ma main. ( Ceci dit ils sont peut-être complémentaires.. )

Après avoir posté, j'ai parcouru le forum plus longuement et, effectivement, je suis tombé sur des discussions entre toi (Djes) et un autre intervenant, lui même en quête d'optimisations. J'ai donc eu l'opportunité d'avoir quelques éclaircissements. :P

Je vais continuer à faire des tests et travailler mon code au 'cas par cas'.

Merci

Re: Comparaison entre trois listing, comment bien analyser ?

Publié : dim. 17/juil./2011 9:31
par comtois
pour info tu peux aussi désassembler avec PureBasic

Code : Tout sélectionner

  DisableDebugger ; do not disassemble any debugger related instructions
  
  Code_Start:
    ; Place code to be disassembled here
    a = (Random(100) * 5) + 2000
  Code_End:
  
  Text$ = "Disassembled code: " + Chr(13)  
  If ExamineAssembly(?Code_Start, ?Code_End)
    While NextInstruction()
      Text$ + RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0")
      Text$ + " " + InstructionString() + Chr(13)
    Wend
  EndIf
  
  MessageRequester("Result", Text$
)