Comparaison entre trois listing, comment bien analyser ?

Pour discuter de l'assembleur
Syntax.error
Messages : 8
Inscription : mer. 13/juil./2011 16:42

Comparaison entre trois listing, comment bien analyser ?

Message 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.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Comparaison entre trois listing, comment bien analyser ?

Message 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.. :)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Comparaison entre trois listing, comment bien analyser ?

Message 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 ;)
Syntax.error
Messages : 8
Inscription : mer. 13/juil./2011 16:42

Re: Comparaison entre trois listing, comment bien analyser ?

Message 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
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Comparaison entre trois listing, comment bien analyser ?

Message 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$
)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Répondre