2017-05-24 2 views
0

J'ai créé un fichier source C++ simple avec le code suivant.Assembly Language to Machine Code

int main() { 
int a = 1; 
int b = 2; 
if(a < b) { 
    return 1; 
} 
else if(a > b) { 
    return 2; 
} 
else { 
    return 3; 
} 

}

Je commande utilisé objdump pour obtenir le code assembleur pour le code source ci-dessus. et la ligne

int b = 2; est converti en mov DWORD PTR [rbp-0x4], 0x2. Le code machine correspondant (format hexadécimal) est c7 45 fc 02 00 00 00 .

Je voulais savoir comment puis-je convertir le code d'assemblage en code binaire. Je suis allé à travers le manuel de référence Intel pour x86-64, mais je ne pouvais pas comprendre, puisque je suis nouveau à la programmation de bas niveau.

+1

Que voulez-vous dire par «convertir»? En utilisant un programme? Le faire manuellement? – Shiro

+0

Conversion manuelle. –

+0

'int b = 2;' n'est PAS un langage d'assemblage.La différence est que C est un langage compilé, donc la ligne 'int b = 2;' peut être implémentée de différentes façons (même complètement supprimée par l'optimiseur), selon ce que le compilateur décidera, comment produire un code machine qui produira résultats tels que définis par la norme de langage C. Le langage d'assemblage est différent d'une certaine façon, Assembler n'est pas un compilateur de ce genre, quand vous écrivez dans Assembly 'add rax, rbx', il sera compilé comme ça, ne changeant pas l'instruction, ou enlevant par un optimiseur, c'est plus comme "transformation 1: 1". – Ped7g

Répondre

4

Vous devriez lire les manuels Intel, il explique comment faire cela. Pour une référence plus simple, read this. La façon dont les instructions x86 sont codées est assez simple, mais le nombre de possibilités peut être un peu écrasant.

En un mot, une instruction x86 comprend les pièces suivantes, où toutes les parties, sauf l'opcode peut être manquant:

prefix opcode operands immediate 

Le champ prefix peut modifier le comportement de l'instruction, qui ne s'applique pas votre cas d'utilisation. Vous pouvez rechercher le opcode dans une référence (J'aime this one), par exemple, mov r/m32, imm32 est C7 /0 ce qui signifie: L'opcode est C7 et l'un des deux opérandes est zéro comme opérande étendu. Cette instruction nécessite 32 bits immédiate, de sorte que l'instruction a la forme

C7 operand/0 imm32 

L'opérande/opcode étendu est codé sous la forme d'un octet MODR/m avec un octet sib en option (base de l'indice d'échelle) pour des modes d'adressage et un déplacement optionnel de 8 ou 32 bits. Vous pouvez rechercher quelle valeur vous avez besoin in the reference. Donc, dans votre cas, vous voulez coder un opérande de mémoire [rbp] avec un déplacement d'un octet et un opérande de registre de 0, conduisant à l'octet modr/m 45. Donc, le codage est:

C7 45 disp8 imm32 

Maintenant, nous codons le déplacement de 8 bits dans le complément à deux. -4 correspond à FC, donc c'est

C7 45 FC imm32 

Enfin, nous chiffrons l'immédiat, 32 bits que vous voulez être 2. Notez qu'il est en petit boutiste:

C7 45 FC 02 00 00 00 

Et c'est ainsi que l'instruction est codée.

+0

Donc, dans le [link] (http://ref.x86asm.net/geek64.html) que vous avez fourni, je suis allé à C7 1 Byte Opcode, et il est pour ** MOV ** instruction. mais que signifient les deux opérandes Evqp \t et Ivds \t, correspondent-ils à l'adressage rm32 et sont-ils immédiats? Merci pour l'aide –

+0

Voir [cette page] (http://ref.x86asm.net/#column_op) pour la signification des champs. La référence que je lie est fortement condensée mais plus difficile à lire. – fuz

+0

Très bien. Une autre question était que vous avez dit "Je voulais coder rbp registre avec 1 octet de déplacement (8 bits) [** DWORD PTR [rbp-0x4] **]", quand je voyais la table pour MOD r/m dans le [ link] (http://ref.x86asm.net/geek64.html#modrm_byte_32_64) Je vois aussi une version des déplacements en 32 bits, peux-tu m'en donner un exemple? –