Re: [Assembleur] cmpxchgq ?

Le Tue, 2 Nov 2010 15:51:04 +0000 (UTC), JKB écrivait :

Bonjour à tous,

Attention, Xpost et Fu2. Le Xpost se fait sur des groupes où je suis totalement hors charte mais où risquent de se trouver des personnes pouvant m'aider à trouver une solution. Merci de me pardonner cette pollution.

Quelques précisions : - j'utilise qemu pour tester (émulation d'un processeur core2 mono coeur). - la machine hôte est une machine avec un core2duo et un système Linux/debian. - la fonctio en question fait partie de la root task d'un OS tournant au-dessus d'un micronoyau L4 (64 bits). - l'assembleur utilisé est GNU as. J'ai naturellement vérifié le code objet en le désassemblant.

Pardonnez-moi cette question à la limite de la charte, mais j'ai un > petit problème avec un bout d'assembleur amd64 trivial (en notation > AT&T) : > > .text > .global try_lock_amd64 > .type try_lock_amd64, @function > .align 16 > > try_lock_amd64: > // Setup the local variables > pushq %rbp > movq %rsp, %rbp > movq 16(%rbp), %rcx /* %rcx = &m->holder */ > movq 24(%rbp), %rdx /* %rdx = me */ > > // Test the lock : > // if (%rcx) == $0, write %rdx into (%rcx) > // if not, write (%rcx) into %rax. > movq $0, %rax > lock > cmpxchgq %rdx, (%rcx) > jz t1 > > // What is the result > movq 16(%rbp), %rax /* %rax = &m->holder */ > movq (%rax), %rax /* %rax = m->holder */ > cmpq 24(%rbp), %rax /* m->holder == me */ > sete %al > andq $255, %rax > > popq %rbp > ret > > t1: pushq %rdx > movq (%rcx), %rdx > pushq %rdx > jmp _Z13dbg$backtracev > > Cette fonction fait partie d'un bout d'OS que je passe en 64 bits. > En 32 bits, ça fonctionne parfaitement. Ce bout de code est appelé > depuis une fonction en C (équivalente à mutex_trylock() pour des > mutexes récursifs). > > Mon problème est simple. Le 'cmpxchgq' ne semble pas faire ce qu'il > devrait (ou alors, je n'ai rien compris). > > Je viens de lire et de relire la doc (origine AMD) et si j'ai bien > tout compris, CMPXCHGQ est censé comparer la valeur de %RAX à la > valeur (%RCX). Si ces deux valeurs sont égales, il copie la valeur > de %RDX dans %(RCX) et met le drapeau Z à 1. > > Dans mon cas, le programme saute à ma routine de débug qui m'affiche > la pile. J'en déduis donc que ce drapeau est à 1 et que CMPXCHGQ > aurait dû copier %RDX dans (%RCX). Je vois bien que %RDX contient la > bonne valeur, mais (%RCX) reste nul comme le prouve la sortie : > > SP -> [$0000000001049428] > +056: [$0000000001049430] -> $0000000000000000 +064: [$0000000001049438] -> $00000000010498D0 +072: [$0000000001049440] -> $0000000001049490 > +080: [$0000000001049448] -> $0000000001001FDD > +088: [$0000000001049450] -> $0000003A00000001 > > Je suppose que j'ai raté quelque chose, mais je ne vois pas quoi. > > Merci de toute lumière, > > JKB >
--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
 Click to see the full signature
Reply to
JKB
Loading thread data ...

On Nov 2, 5:48 pm, JKB

Gn=EE !

Bon, je me lance :

  1. As-tu essay=E9 de changer cmpxchgq par une suite de codes =E9quivalents pour comparer le r=E9sultat ? Un truc de ce genre ( si j'ai bien tout suivi ) cmp eax,edx bne skip mov edx,ecx skip ...

  1. Il me semble que cmpxchgq compare le RESTE d'un modulo 8, 16 ou 32 selon le cas. Sachant que ton code tourne en 32 bits mais pas en 64, y a t'il une chance que ce soit du =E0 ce remainder ?

"CMPXCHG r/m8, r8 Compare AL with r/m8. If equal, ZF is set and r8 is loaded into r/m8. Else, clear ZF and load r/m8 into AL." "CMPXCHG r/m16, r16 Compare AX with r/m16. If equal, ZF is set and r16 is loaded into r/m16. Else, clear ZF and load r/m16 into AL" "CMPXCHG r/m32, r32 Compare EAX with r/m32. If equal, ZF is set and r32 is loaded into r/m32. Else, clear ZF and load r/m32 into AL"

HTH ...

suis

nnes

ette

ono

=E8me

=E9 le

n
n

=E9

l

iche

la

=E8s

Reply to
Jean-Christophe

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.