Bonjour à tous,
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
+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
Bonjour à tous,
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
+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
Bonjour à tous,
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
+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
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
+072: [$0000000001049440] -> $0000000001049490
+080: [$0000000001049448] -> $0000000001001FDD
+088: [$0000000001049450] -> $0000003A00000001
Je suppose que j'ai raté quelque chose, mais je ne vois pas quoi.
Le Tue, 2 Nov 2010 15:51:04 +0000 (UTC),
JKB <jkb@koenigsberg.invalid> é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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
+072: [$0000000001049440] -> $0000000001049490
+080: [$0000000001049448] -> $0000000001001FDD
+088: [$0000000001049450] -> $0000003A00000001
Je suppose que j'ai raté quelque chose, mais je ne vois pas quoi.
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
+072: [$0000000001049440] -> $0000000001049490
+080: [$0000000001049448] -> $0000000001001FDD
+088: [$0000000001049450] -> $0000003A00000001
Je suppose que j'ai raté quelque chose, mais je ne vois pas quoi.
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
Disons valeur de %rdx après le cmpxchg, valeur /attendue/ dans (%rcx),
non ?
+072: [$0000000001049440] -> $0000000001049490
+080: [$0000000001049448] -> $0000000001001FDD
+088: [$0000000001049450] -> $0000003A00000001
Je suppose que j'ai raté quelque chose, mais je ne vois pas quoi.
Je suis de votre avis, c'est étrange. Il semble que vous ayez peu de
moyens d'investigation. Peut-être %rcx pointe vers un segment non
/writable/, et le #BG(0) est silencieux (et fait des choses utiles) ?
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
Disons valeur de %rdx après le cmpxchg, valeur /attendue/ dans (%rcx),
non ?
+072: [$0000000001049440] -> $0000000001049490
+080: [$0000000001049448] -> $0000000001001FDD
+088: [$0000000001049450] -> $0000003A00000001
Je suppose que j'ai raté quelque chose, mais je ne vois pas quoi.
Je suis de votre avis, c'est étrange. Il semble que vous ayez peu de
moyens d'investigation. Peut-être %rcx pointe vers un segment non
/writable/, et le #BG(0) est silencieux (et fait des choses utiles) ?
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 <- pourquoi 0 ?!
+064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
Disons valeur de %rdx après le cmpxchg, valeur /attendue/ dans (%rcx),
non ?
+072: [$0000000001049440] -> $0000000001049490
+080: [$0000000001049448] -> $0000000001001FDD
+088: [$0000000001049450] -> $0000003A00000001
Je suppose que j'ai raté quelque chose, mais je ne vois pas quoi.
Je suis de votre avis, c'est étrange. Il semble que vous ayez peu de
moyens d'investigation. Peut-être %rcx pointe vers un segment non
/writable/, et le #BG(0) est silencieux (et fait des choses utiles) ?
JKB, le 11/2/2010 a écrit :
[...]
Je viens de tout relire et de piger que vous écriviez le code. A ce
moment-là, il serait peut-être intéressant dans t1 d'empiler %rcx et
non (%rcx), juste pour voir. Et aussi de tenter:
movq magic, (%rcx)
movq (%rcx), %rdx
pushq %rdx
JKB, le 11/2/2010 a écrit :
[...]
Je viens de tout relire et de piger que vous écriviez le code. A ce
moment-là, il serait peut-être intéressant dans t1 d'empiler %rcx et
non (%rcx), juste pour voir. Et aussi de tenter:
movq magic, (%rcx)
movq (%rcx), %rdx
pushq %rdx
JKB, le 11/2/2010 a écrit :
[...]
Je viens de tout relire et de piger que vous écriviez le code. A ce
moment-là, il serait peut-être intéressant dans t1 d'empiler %rcx et
non (%rcx), juste pour voir. Et aussi de tenter:
movq magic, (%rcx)
movq (%rcx), %rdx
pushq %rdx
Le Tue, 02 Nov 2010 20:02:34 +0100,
Pierre Maurette écrivait :
movq magic, (%rcx)
lock/lock_mutex_amd64.S:63: Error: too many memory references for `movq'
Je ne connais pas cette syntaxe (et mon compilo non plus).
Le Tue, 02 Nov 2010 20:02:34 +0100,
Pierre Maurette <maurettepierre@wanadoo.fr> écrivait :
movq magic, (%rcx)
lock/lock_mutex_amd64.S:63: Error: too many memory references for `movq'
Je ne connais pas cette syntaxe (et mon compilo non plus).
Le Tue, 02 Nov 2010 20:02:34 +0100,
Pierre Maurette écrivait :
movq magic, (%rcx)
lock/lock_mutex_amd64.S:63: Error: too many memory references for `movq'
Je ne connais pas cette syntaxe (et mon compilo non plus).
JKB, le 11/2/2010 a écrit :Le Tue, 02 Nov 2010 20:02:34 +0100,
Pierre Maurette écrivait :
[...]movq magic, (%rcx)
lock/lock_mutex_amd64.S:63: Error: too many memory references for `movq'
Je ne connais pas cette syntaxe (et mon compilo non plus).
Par /magic/, je voulais dire une valeur quelconque au hasard, pas 0 par
exemple.
JKB, le 11/2/2010 a écrit :
Le Tue, 02 Nov 2010 20:02:34 +0100,
Pierre Maurette <maurettepierre@wanadoo.fr> écrivait :
[...]
movq magic, (%rcx)
lock/lock_mutex_amd64.S:63: Error: too many memory references for `movq'
Je ne connais pas cette syntaxe (et mon compilo non plus).
Par /magic/, je voulais dire une valeur quelconque au hasard, pas 0 par
exemple.
JKB, le 11/2/2010 a écrit :Le Tue, 02 Nov 2010 20:02:34 +0100,
Pierre Maurette écrivait :
[...]movq magic, (%rcx)
lock/lock_mutex_amd64.S:63: Error: too many memory references for `movq'
Je ne connais pas cette syntaxe (et mon compilo non plus).
Par /magic/, je voulais dire une valeur quelconque au hasard, pas 0 par
exemple.
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 perso nnes
pouvant m'aider à trouver une solution. Merci de me pardonner c ette
pollution.
Quelques précisions :
- j'utilise qemu pour tester (émulation d'un processeur core2 m ono
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 u n
> petit problème avec un bout d'assembleur amd64 trivial (en notatio n
> 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'i l
> 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'aff iche
> 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 <- pourquoi 0 ?!
> +064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
> +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...
=>http://grincheux.de-charybde-en-scylla.fr
Le Tue, 2 Nov 2010 15:51:04 +0000 (UTC),
JKB <j...@koenigsberg.invalid> é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 perso nnes
pouvant m'aider à trouver une solution. Merci de me pardonner c ette
pollution.
Quelques précisions :
- j'utilise qemu pour tester (émulation d'un processeur core2 m ono
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 u n
> petit problème avec un bout d'assembleur amd64 trivial (en notatio n
> 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'i l
> 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'aff iche
> 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 <- pourquoi 0 ?!
> +064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
> +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...
=>http://grincheux.de-charybde-en-scylla.fr
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 perso nnes
pouvant m'aider à trouver une solution. Merci de me pardonner c ette
pollution.
Quelques précisions :
- j'utilise qemu pour tester (émulation d'un processeur core2 m ono
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 u n
> petit problème avec un bout d'assembleur amd64 trivial (en notatio n
> 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'i l
> 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'aff iche
> 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 <- pourquoi 0 ?!
> +064: [$0000000001049438] -> $00000000010498D0 <- valeur correcte de %rcx
> +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...
=>http://grincheux.de-charybde-en-scylla.fr
Il y a un truc bizarre lorsque je remplace 0 par une valeur non
nulle. Je vais laisser tomber pour ce soir...
Il y a un truc bizarre lorsque je remplace 0 par une valeur non
nulle. Je vais laisser tomber pour ce soir...
Il y a un truc bizarre lorsque je remplace 0 par une valeur non
nulle. Je vais laisser tomber pour ce soir...