Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug dans la génération de code assembleur #7950

Closed
vicuna opened this issue Nov 13, 2002 · 1 comment
Closed

Bug dans la génération de code assembleur #7950

vicuna opened this issue Nov 13, 2002 · 1 comment
Labels

Comments

@vicuna
Copy link

vicuna commented Nov 13, 2002

Original bug ID: 1474
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Bonjour à tous,

voici un bug découvert par un de mes étudiants. Il s'agit d'un problème
de génération de code assembleur.
Je joins le source du programme qui déclenche le bug.

Le message d'erreur du compilateur (en fait, de l'assembleur) est le
suivant:
/tmp/camlasm1.s: Assembler messages:
/tmp/camlasm1.s:1716: Error: suffix or operands invalid for `imul'
Assembler error, input left in file /tmp/camlasm1.s

Un coup d'oeil sur la ligne incriminée (1716)
imull $10, 16(%esp)
montre qu'il s'agit effectivement d'un mode d'adressage invalide. L'IA32
accepte que le source soit dans la pile, mais pas la destination, pour
une multiplication entière.

La ligne du programme ML qui provoque ce bug est semble-t-il la ligne
170.

Le bug se produit avec les version 3.04, 3.06 ainsi que la 3.06+18
récupéré sur le serveur CVS.

Le bug disparait si l'on compile avec -unsafe...
Les voies du compilateur OCAML sont parfois impénétrables...

Merci

--
| Jean-Marc Alliot |
| mailto:alliot@recherche.enac.fr |
| http://www.recherche.enac.fr/~alliot |


(* ABALONE by Benny v1.1 : classe les coups *)

()
(
DEFINITIONS )
(
)

(* coefficients d'evaluation *)
let p1 = 700;;
let p2 = 100.;;
let p3 = 2;;

let print = false;;

(* constantes *)
let tabl = Array.create_matrix 11 11 0;;
let prof = ref 1;;
let out_p = ref 0;;
let out_m = ref 0;;
let inf = 100000000;;
let dir_tab = [|(0,1);(1,1);(1,0);(0,-1);(-1,-1);(-1,0);(0,1);(1,1);(1,0);(0,-1);(-1,-1);(-1,0)|];;
let dir_x = [|0;1;1;0;-1;-1;0;1;1;0;-1;-1|];;
let dir_y = [|1;1;0;-1;-1;0;1;1;0;-1;-1;0|];;
let dir_inv = [| [|4 ; 3 ; -1|] ; [|5 ; -1 ; 2|] ; [|-1 ; 0 ; 1|] |];;

(* position de depart )
let init () =
for i=1 to 5 do tabl.(i).(1) <- 1 done; (
les noirs )
for i=1 to 6 do tabl.(i).(2) <- 1 done;
for i=3 to 5 do tabl.(i).(3) <- 1 done;
for i=5 to 7 do tabl.(i).(7) <- -1 done; (
les blancs )
for i=4 to 9 do tabl.(i).(8) <- -1 done;
for i=5 to 9 do tabl.(i).(9) <- -1 done;
for i=0 to 5 do tabl.(i).(0) <- 2 done; (
les cases exterieures *)
for i=5 to 10 do tabl.(i).(10) <- 2 done;
for i=1 to 5 do tabl.(0).(i) <- 2 done;
for i=5 to 9 do tabl.(10).(i) <- 2 done;
for i=1 to 4 do tabl.(i+5).(i) <- 2 done;
for i=1 to 4 do tabl.(i).(i+5) <- 2 done;;

(* tableau d'evaluation *)
let eval = Array.create 4096 0;;

let rec puissance a n =
if n=0 then 1
else (a * (puissance a (n-1)));;

let eval_create =
for i=0 to 4095 do
begin
(* un voisin )
for v=0 to 5 do
(match ((i/(puissance 4 v)) mod 4) with
| 0 -> (eval.(i) <- (eval.(i) + 0)) (
0 )
| 1 -> (eval.(i) <- (eval.(i) + 1)) (
cp*)
| 2 -> (eval.(i) <- (eval.(i) - 5)) (out)
| 3 -> (eval.(i) <- (eval.(i) + 0)) (-cp)
| _ -> () )
done;
(* deux voisins )
for v=0 to 5 do
(match ((i/(puissance 4 v)) mod 4) with
| 1 ->
if ((i/(puissance 4 ((v+1) mod 6))) mod 4)=1 then (eval.(i) <- (eval.(i) + 1)) else (); (
ami ortho )
if ((i/(puissance 4 ((v+2) mod 6))) mod 4)=1 then (eval.(i) <- (eval.(i) + 1)) else (); (
ami meta )
if ((i/(puissance 4 ((v+3) mod 6))) mod 4)=1 then (eval.(i) <- (eval.(i) + 4)) else (); (
ami para )
| 3 ->
if ((i/(puissance 4 ((v+1) mod 6))) mod 4)=3 then (eval.(i) <- (eval.(i) + 0)) else (); (
eni ortho )
if ((i/(puissance 4 ((v+2) mod 6))) mod 4)=3 then (eval.(i) <- (eval.(i) + 0)) else (); (
eni meta )
if ((i/(puissance 4 ((v+3) mod 6))) mod 4)=3 then (eval.(i) <- (eval.(i) + 2)) else (); (
eni para )
| _ -> () )
done;
end
done;
(
six voisins )
eval.(1365) <- 50; (
6 amis )
eval.(4095) <- 10;; (
6 ennemis *)

(* afficher la position )
let print_matrix () =
for i=0 to 10 do
(match (10-i) with
| 0 -> print_string " "
| 1 -> print_string " "
| 2 -> print_string " "
| 3 -> print_string " "
| 4 -> print_string " "
| 5 -> print_string " "
| 6 -> print_string " "
| 7 -> print_string " "
| 8 -> print_string " "
| 9 -> print_string " "
| 10 -> print_string ""
| _ -> () );
for j=0 to 10 do
(match tabl.(j).(10-i) with
| 0 -> print_string "."
| -1 -> print_string "o"
| 1 -> print_string "+"
| 2 -> print_string "
"
| _ -> () );
print_string " "
done;
print_newline ()
done;
print_string "score : ";
print_int !out_m;
print_string " / ";
print_int !out_p;
print_newline ();;

()
(
LES COUPS )
(
)

(* coup normalise -> code perso )
let cnp coup =
let x1 = coup / 10000000
and y1 = coup / 1000000 - 10 * (coup / 10000000)
and x2 = coup / 100000 - 10 * (coup / 1000000)
and y2 = coup / 10000 - 10 * (coup / 100000)
and x3 = coup / 1000 - 10 * (coup / 10000)
and y3 = coup / 100 - 10 * (coup / 1000)
and x4 = coup / 10 - 10 * (coup / 100)
and y4 = coup - 10 * (coup / 10) in
if coup<10000 then (
coup en ligne )
begin
let dx = (x4-x3) / (max 1 (abs (x4-x3)))
and dy = (y4-y3) / (max 1 (abs (y4-y3))) in
let d = dir_inv.(dx+1).(dy+1)
and l = max (abs (x4-x3)) (abs (y4-y3)) in
let mb = ref 0 in
while (abs tabl.(x4 + (!mb
dx)).(y4 + (!mbdy)) = 1) do
incr mb
done;
if (tabl.(x4 + (!mb
dx)).(y4 + (!mbdy)) = 2) then
(10000 + x3
1000 + y3100 + d10 + l + !mb)
else
(x31000 + y3100 + d10 + l + !mb)
end
else (
coup en fleche )
begin
let dx = (x4-x2) / (max 1 (abs (x4-x2)))
and dy = (y4-y2) / (max 1 (abs (y4-y2)))
and vx = (x4-x3) / (max 1 (abs (x4-x3)))
and vy = (y4-y3) / (max 1 (abs (y4-y3))) in
let d = dir_inv.(dx+1).(dy+1)
and v = dir_inv.(vx+1).(vy+1)
and l = 1 + max (abs (x3-x1)) (abs (y3-y1)) in
((6+v)10000 + x11000 + y1
100 + d*10 + l)
end;;

(* code perso -> coup normalise )
let cpn code =
let v = code / 10000
and x = code / 1000 - 10 * (code / 10000)
and y = code / 100 - 10 * (code / 1000)
and (dx,dy) = dir_tab.(code / 10 - 10 * (code / 100))
and l = code - 10 * (code / 10) in
if v<2 then
match l with
| 5 -> (x
1000 + y100 + (x+3dx)10 + (y+3dy))
| 4 -> (x1000 + y100 + (x+3dx)10 + (y+3dy))
| 3 ->
if tabl.(x+2
dx).(y+2dy)=tabl.(x).(y)
then (x
1000 + y100 + (x+3dx)10 + (y+3dy))
else (x1000 + y100 + (x+2dx)10 + (y+2dy))
| _ -> (x
1000 + y100 + (x+ldx)10 + (y+ldy))
else
let (vx,vy) = dir_tab.(v) in
(x10000000 + y1000000 + (x+vx)*100000 + (y+vy)*10000 + (x+(l-1)*dx)*1000 + (y+(l-1)*dy)*100 + (x+vx+(l-1)*dx)*10 + (y+vy+(l-1)*dy));;

(* coup humain -> coup normalise )
let coup_humain () =
let gg = ref true
and p1 = ref 0
and p2 = ref 0
and p3 = ref 0
and p4 = ref 0 in
print_string "A vous de jouer.";
while !gg do
print_string "Coup en ligne (l) ou coup en fleche (f) ? ";
if (read_line () = "f") then
begin
print_string "Coordonnees de la bille poussee ? ";
p1 := read_int ();
print_string "Coordonnees de la position d'arrivee ? ";
p2 := read_int ();
end
else ();
print_string "Coordonnees de la bille poussee ? ";
p3 := read_int ();
print_string "Coordonnees de la position d'arrivee ? ";
p4 := read_int ();
print_newline ();
print_int (!p1
1000000 + !p210000 + !p3100 + !p4);
print_newline ();
print_string "Ce coup est-il correct (y/n) ? ";
if (read_line () = "y") then (gg :=false)
else ()
done;
(!p11000000 + !p210000 + !p3*100 + !p4);;

(* coups en avant )
let coup_avant code =
let v = code / 10000
and x = code / 1000 - 10 * (code / 10000)
and y = code / 100 - 10 * (code / 1000)
and (dx,dy) = dir_tab.(code / 10 - 10 * (code / 100))
and l = code - 10 * (code /10) in
if v<2 then (
coup en ligne )
begin
if v=1 then
if tabl.(x).(y)=1
then incr out_m
else incr out_p
else ();
for i=(v+1) to l do
tabl.(x + (l+1-i)dx).(y + (l+1-i)dy) <- tabl.(x + (l-i)dx).(y + (l-i)dy)
done;
tabl.(x).(y) <- 0
end
else (
coup en fleche )
begin
let (vx,vy) = dir_tab.(v) in
for i=0 to l-1 do
tabl.(x + i
dx + vx).(y + i
dy + vy) <- tabl.(x + i
dx).(y + i
dy);
tabl.(x + i
dx).(y + i*dy) <- 0
done;
end;;

(* coups en arriere )
let coup_arriere code =
let v = code / 10000
and x = code / 1000 - 10 * (code / 10000)
and y = code / 100 - 10 * (code / 1000)
and (dx,dy) = dir_tab.(code / 10 - 10 * (code / 100))
and l = code - 10 * (code /10) in
if v<2 then (
coup en ligne )
begin
for i=0 to l-1-v do
tabl.(x + i
dx).(y + idy) <- tabl.(x + (i+1)dx).(y + (i+1)dy)
done;
if v=0 then
tabl.(x + l
dx).(y + l
dy) <- 0
else
begin
tabl.(x + (l-1)dx).(y + (l-1)dy) <- (-tabl.(x).(y));
if tabl.(x).(y)=1
then decr out_m
else decr out_p
end
end
else (
coup en fleche )
begin
let (vx,vy) = dir_tab.(v) in
for i=0 to l-1 do
tabl.(x + i
dx).(y + i
dy) <- tabl.(x + i
dx + vx).(y + idy + vy);
tabl.(x + i
dx + vx).(y + i*dy + vy) <- 0
done;
end;;

(* generateur de coups )
let gen cp =
let list = ref []
and cont = ref true
and x = ref 0
and y = ref 0
and bb = ref 0
and mb = ref 0 in
for i=1 to 9 do
for j=max 1 (i-4) to min 9 (i+4) do
if tabl.(i).(j)=cp then
begin
for d=1 to 6 do
let (dx,dy) = dir_tab.(d) in
cont := true;
x := i;
y := j;
bb := 1;
mb := 0;
while !cont do
x := !x + dx;
y := !y + dy;
match tabl.(!x).(!y)cp with
| 1 ->
incr bb;
if (!bb > 3 or !mb > 0)
then cont := false
else
begin (
coups en fleche )
let (vx1,vy1) = dir_tab.(d+1) in
let (vx2,vy2) = dir_tab.(d+2) in
if (tabl.(i+vx1).(j+vy1)=0 && tabl.(i+dx+vx1).(j+dy+vy1)=0 && tabl.(!x+vx1).(!y+vy1)=0)
then (list := (((d+1)10000 + i1000 + j
100 + d
10 + !bb) :: !list))
else ();
if (tabl.(i+vx2).(j+vy2)=0 && tabl.(i+dx+vx2).(j+dy+vy2)=0 && tabl.(!x+vx2).(!y+vy2)=0)
then (list := (((d+2)10000 + i1000 + j100 + d10 + !bb) :: !list))
else ()
end
| -1 ->
incr mb;
if (!mb = !bb)
then cont := false
else ()
| 0 -> (* coups en ligne sans ejection )
list := ((i
1000 + j100 + d10 + !bb + !mb) :: !list);
cont := false
| _ ->
if (!mb>0) (* coups en ligne avec ejection )
then list := ((10000 + i
1000 + j100 + d10 + !bb + !mb) :: !list)
else ();
cont := false
done
done
end
done
done;
!list;;

()
(* EVALUATION *)
(
)

(* distance *)
let dist_int i j k l =
let dx = (abs (k-i))
and dy = (abs (l-j))
and dz = (abs (k-i-l+j)) in
dx + dy + dz - (max (max dx dy) dz);;

let dist_float i j k l =
let dx = (abs_float (k-.i))
and dy = (abs_float (l-.j))
and dz = (abs_float (k-.i-.l+.j)) in
dx +. dy +. dz -. (max (max dx dy) dz);;

(* evaluation de l'environnement d'une bille *)
let env i j =
let a = ref 0
and b = ref 0 in
for k=0 to 5 do
begin
a := (tabl.(i + dir_x.(k)).(j + dir_y.(k)) * tabl.(i).(j) + 4) mod 4;
b := !b + !a * (puissance 4 k);
end
done;
eval.(!b);;

(* fonction d'evaluation *)
let evaluate () =
let sigx_p = ref 0
and sigy_p = ref 0
and sigx_m = ref 0
and sigy_m = ref 0
and env_p = ref 0
and env_m = ref 0 in
for i=1 to 9 do
for j=max 1 (i-4) to min 9 (i+4) do
match tabl.(i).(j) with
| 0 -> ()
| 1 ->
begin
sigx_p := !sigx_p + i;
sigy_p := !sigy_p + j;
env_p := !env_p + env i j
end
| -1 ->
begin
sigx_m := !sigx_m + i;
sigy_m := !sigy_m + j;
env_m := !env_m + env i j
end
| _ -> ()
done
done;
let barx_p = (float !sigx_p) /. (float (14 - !out_p))
and bary_p = (float !sigy_p) /. (float (14 - !out_p))
and barx_m = (float !sigx_m) /. (float (14 - !out_m))
and bary_m = (float !sigy_m) /. (float (14 - !out_m)) in
let centr_p = dist_float 5. 5. barx_p bary_p
and centr_m = dist_float 5. 5. barx_m bary_m in

if print then
begin
print_string "1/centrage + : ";
print_float (1. /. centr_p);
print_newline ();
print_string "difference de centrage : ";
print_float (p2 *. (1. /. centr_p -. 1. /. centr_m));
print_newline ();
print_string "difference d'environnement : ";
print_int (p3 * (!env_p - !env_m));
print_newline ();
end
else ();

(p1 * (!out_m - !out_p) + int_of_float(p2 *. (centr_m -. centr_p)) + p3 * (!env_p - !env_m));;

()
(* ALPHA-BETA *)
(
)

let comp coup_1 coup_2 =
coup_avant coup_1;
let e1 = evaluate () in
coup_arriere coup_1;
coup_avant coup_2;
let e2 = evaluate () in
coup_arriere coup_2;
e1-e2;;

let rec ab p alpha beta cp =
let a = ref alpha
and b = ref beta in
let l = ref (gen cp) in
if (p=1) then
begin
if (cp>0) then
begin
while ((!a)<(!b) && (!l<>[])) do
coup_avant (List.hd !l);
a := max !a (evaluate ());
coup_arriere (List.hd !l);
l := List.tl !l
done;
!a
end
else
begin
while ((!a)<(!b) && (!l<>[])) do
coup_avant (List.hd !l);
b := min !b (evaluate ());
coup_arriere (List.hd !l);
l := List.tl !l
done;
!b
end
end
else
begin
if (cp>0) then
begin
while ((!a)<(!b) && (!l<>[])) do
coup_avant (List.hd !l);
a := max !a (ab (p-1) !a !b (-cp));
coup_arriere (List.hd !l);
l := List.tl !l
done;
!a
end
else
begin
while ((!a)<(!b) && (!l<>[])) do
coup_avant (List.hd !l);
b := min !b (ab (p-1) !a !b (-cp));
coup_arriere (List.hd !l);
l := List.tl !l
done;
!b
end
end;;

let ab1 p0 cp =
let a = ref (-inf)
and b = ref (inf)
and c = ref 0
and e = ref 0 in
let l = ref (List.sort comp (gen cp)) in
if (cp>0) then
begin
l := List.rev !l; (* classer par evaluation decroissante pour cp=1 *)
while (!l<>[]) do
coup_avant (List.hd !l);
e := ab (p0-1) !a !b (-cp);
coup_arriere (List.hd !l);
if ((!e)>(!a)) then
begin
c := List.hd !l;
a := !e
end
else ();
l := List.tl !l
done
end
else
begin
while (!l<>[]) do
coup_avant (List.hd !l);
e := ab (p0-1) !a !b (-cp);
coup_arriere (List.hd !l);
if ((!e)<(!b)) then
begin
c := List.hd !l;
b := !e
end
else ();
l := List.tl !l
done
end;
!c;;

()
(* GESTIONNAIRE DE PARTIE *)
(
)

(* jouer un coup et afficher *)
let playshow code =
coup_avant code;
print_matrix ();
print_int (evaluate ());
print_newline ();;

(* jouer avec le serveur *)

(* jouer contre moi-meme *)
let solo () =
let cp = ref 1 in
print_string "Partie de demonstration.";
print_newline ();
print_matrix ();
while ((!out_p <6) && (!out_m <6)) do
playshow (ab1 !prof !cp);
cp := (- !cp)
done;;

(* jouer contre humain *)
let humain () =
let cp = ref 0 in
print_string "Voulez-vous commencer ? (y/n) ";
if (read_line () = "y") then
begin
cp := -1;
print_newline ();
print_string "Vous avez les noirs. Vous commencez.";
print_newline ();
print_matrix ();
playshow (cnp (coup_humain ()))
end
else
begin
cp := 1;
print_newline ();
print_string "Vous avez les blancs. Les noirs commencent.";
print_newline ();
print_matrix ()
end;
while ((!out_p <6) && (!out_m <6)) do
playshow (ab1 !prof !cp);
playshow (cnp (coup_humain ()))
done;
if ((!out_p = 6 && !cp = 1) || (!out_m = 6 && !cp = -1)) then
print_string "Bien joue !"
else
print_string "Ce traitement est inhumain, n'est-ce pas ?";
print_newline ();;

(* main *)
let main =
print_string "Bienvenue sur Abalone";
print_newline();
init ();
prof := 4;
solo ();;



@vicuna
Copy link
Author

vicuna commented Nov 22, 2002

Comment author: administrator

Fixed 2002-11-22 by XL

@vicuna vicuna closed this as completed Nov 22, 2002
@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant