Recientemente tuve que depurar un programa en el nivel de ensamblaje. No tengo mucha experiencia como ensamblador, así que pensé que escribiría algunos programas simples de C y un solo paso a través de ellos para tener una idea del idioma antes de comenzar a depurar el código de otras personas. Sin embargo, realmente no entiendo lo que gcc hecho de estas dos líneas (compilado con -O0 -ggdb):¿Cómo funciona esta pieza de montaje?
items[tail] = i;
tail = (tail+1) % MAX_SIZE;
donde se MAX_SIZE #defined ser 5 e i es una variable local (almacenado en 0x8 (% ebp), supongo). De acuerdo con el BGF, esto se convierte en:
0x08048394 <queue+17>: mov 0x8049634,%edx
0x0804839a <queue+23>: mov 0x8(%ebp),%eax
0x0804839d <queue+26>: mov %eax,0x804963c(,%edx,4)
0x080483a4 <queue+33>: mov 0x8049634,%eax
0x080483a9 <queue+38>: lea 0x1(%eax),%ecx
0x080483ac <queue+41>: movl $0x66666667,-0xc(%ebp)
0x080483b3 <queue+48>: mov -0xc(%ebp),%eax
0x080483b6 <queue+51>: imul %ecx
0x080483b8 <queue+53>: sar %edx
0x080483ba <queue+55>: mov %ecx,%eax
0x080483bc <queue+57>: sar $0x1f,%eax
0x080483bf <queue+60>: mov %edx,%ebx
0x080483c1 <queue+62>: sub %eax,%ebx
0x080483c3 <queue+64>: mov %ebx,-0x8(%ebp)
0x080483c6 <queue+67>: mov -0x8(%ebp),%eax
0x080483c9 <queue+70>: shl $0x2,%eax
0x080483cc <queue+73>: add -0x8(%ebp),%eax
0x080483cf <queue+76>: mov %ecx,%edx
0x080483d1 <queue+78>: sub %eax,%edx
0x080483d3 <queue+80>: mov %edx,-0x8(%ebp)
0x080483d6 <queue+83>: mov -0x8(%ebp),%ebx
0x080483d9 <queue+86>: mov %ebx,0x804963
Desde 0x804963c es la dirección de los envíos, puedo ver cómo la primera línea de código C funciona. Además, 0x8049634 es la dirección de cola, así que supongo que cola + 33 y cola + 38 son equivalentes a% ecx = cola + 1 ... pero no tengo idea de lo que está sucediendo después. ¿Quién hubiera pensado que un módulo simple podría ser tan complicado?