Mirando el nivel del código de operación, las primeras instrucciones de cualquier contrato inteligente comienzan con esto:
push1 80
push1 40
mstore
Entiendo que esto guarda 0x80 para abordar 0x40, pero ¿para qué sirve todo esto? Investigué el documento Ethereum Yellow, pero nunca mencionó esto en ninguna parte.
Gracias.
Los documentos de solidez establecen lo siguiente:
"Solidity administra la memoria de una manera muy simple: hay un "puntero de memoria libre" en la posición 0x40 en la memoria. Si desea asignar memoria, simplemente use la memoria a partir de ese momento y actualice el puntero en consecuencia".
Referencia: https://solidity.readthedocs.io/en/v0.4.21/assembly.html
editar
Ejemplo de los documentos:
mstore(0x40, 0x60) // store the "free memory pointer"
// ...
// memory allocator
function $allocate(size) -> pos {
pos := mload(0x40)
mstore(0x40, add(pos, size))
}
Primero, almacena la dirección 0x60 como el puntero de memoria actual usando mstore(adr, value) para almacenar 32 bytes. Luego crea una función, asignar (tamaño). La función allocate(size) funciona de la siguiente manera: dado el tamaño del argumento, la persona que llama a la función puede especificar cuánta memoria requiere el programa. Luego, la función carga el "puntero de memoria libre" actual en la dirección 0x40 (que es 0x60 antes de llamar a esta función por primera vez en este caso) y le agrega tamaño . Después de esto, la función devuelve el nuevo "puntero de memoria libre" y el programador puede simplemente usar los bytes de tamaño que el programa ha asignado.
edición 2: ejemplo concreto
No tengo mucha experiencia en la codificación de código ensamblador para EVM, así que tenga en cuenta que el siguiente ejemplo podría estar equivocado. Intentaré dar un ejemplo que muestre cómo asignar espacio (32 bytes) para una variable, almacenar un valor, leer el valor y finalmente liberar la memoria.
// prepare our variables
// x = variable used to store the contents of the allocated memory
// p = current "free memory pointer"
let x := 0
let p := mload(0x40)
// allocate 32 bytes of space
mstore(0x40, add(p, 0x20))
// store up to 32 bytes in the allocated space
mstore(p, 0xDEADBEEF)
// load the value we just stored
x := mload(p)
// We don't need the allocated space anymore. Free it.
mstore(0x40, p)
usuario311703
mar212
usuario311703