2012-07-01 3 views
0

Je dois choisir le bon outil pour appeler une fonction foo que écrit en c. foo obtient 1 arguments 0x100fa500.Instruction push dans assembly (intel 8086)

la première réponse est:

sub esp,2 
mov word[esp],0xa500 
sub esp,2 
mov word[esp] , 0x100f 
call foo 
add esp 4 

et le second:

sub esp,2 
mov word[esp],0x100f 
sub esp,2 
mov word[esp] , 0xa500 
call foo 

pourquoi le second est vrai? Je pense que le premier implémenter le bon paramètre push puis appeler

+0

Marquer comme devoir peut-être? – ndkrempel

Répondre

3

Mis à part le add esp, 4 manquant à la fin, la deuxième version est correcte, comme l'architecture Intel est peu endian. Cela signifie qu'un DWORD est stocké en mémoire avec son BYTE ou WORD le moins significatif occupant l'adresse de mémoire inférieure. Dans votre cas, 0xA500 est le MOT le moins significatif du DWORD, et la deuxième version le place correctement dans les 2 octets inférieurs d'une zone de 4 octets de la pile.

+0

mais n'est pas le début de pile de l'adresse haute? je veux dire, si je vais exécuter le premier code, j'obtiendrai: 10 dans l'adresse la plus basse de la pile et 00 dans le plus haut. j'obtiendrai si je fais: poussée 0x100fa500. Ai-je raison? et c'est aussi ce que – user1462787

+0

@ user1462787: tout ce que vous dites est cohérent avec une architecture big-endian, ce qui n'est pas le cas ici. Le fait que vous essayez de mettre 10 dans l'adresse la plus basse de la pile est déjà faux. En fait, le premier code mettra 0F dans l'adresse la plus basse de la pile - vous faites en fait la même erreur deux fois (une fois pour l'ordre des octets dans un DWORD, lié à la question et une fois pour l'ordre des octets dans un MOT, lié au fonctionnement d'une instruction 'mov'.) – ndkrempel

+0

@ user1462787: Votre confusion est peut-être liée au fait que la pile se développe vers le bas. En ce sens, la pile est "en arrière", mais les éléments de données individuels dans la pile sont stockés dans leur ordre normal, sinon vous ne seriez pas en mesure d'y accéder correctement avec des 'mov's de taille DWORD et WORD standard. – ndkrempel

0

Cela dépend de la convention d'appel mais pour "cdecl" c'est à l'appelant de nettoyer la pile. Ce qui signifie que c'est votre première réponse qui est correcte car elle fait "ajouter esp, 4". Cependant, tout comme ndkrempel remarque dans sa réponse, le paramètre devrait être passé comme little-endian comme dans la deuxième réponse.

http://en.wikipedia.org/wiki/X86_calling_conventions

+0

Je pense que le nettoyage de la pile de l'appelant ou non est juste une faute de frappe dans la question. Remarquez que l'ordre des 'mov's diffère - je pense que c'est l'axe principal de la question. – ndkrempel

+0

@ndkrempel: Je pense que vous avez raison. J'ai édité ma réponse. Et c'est en effet probablement une question de devoirs :-) –

Questions connexes