Estoy aprendiendo el ensamblaje en línea en Solidity, encontré la función mload(0x40)
. Estoy confundido con lo que hace esta función. ¿Reservó 4 ranuras/palabra en memoria o cargó los datos almacenados en la dirección 0X40 o qué?
mload(0xAB)
Carga la palabra (32 bytes) ubicada en la dirección de memoria 0xAB. por ejemplo mload(0x60)
, carga la palabra ubicada en la dirección de memoria 0x60.
Vamos a codificar para entender más:
function f ()
{
assembly {
let freemem_pointer := mload(0x40)
mstore(add(freemem_pointer,0x00),"36e5236fcd4c61044949678014f0d085")
mstore(add(freemem_pointer,0x20),"36e5236fcd4c61044949678014f0d086")
let arr1:= mload(freemem_pointer) //read first string
mstore(add(freemem_pointer,0x40),arr1)
}
}
esto da como resultado el estado de memoria fluida:
Este código anterior almacena dos cadenas (dos palabras de memoria de 32 bytes cada una) en el espacio de memoria libre. Las direcciones de memoria de destino se obtienen sumando un desplazamiento de 0 bytes para el primero y de 0x20 para el segundo a la dirección del puntero de memoria libre (ubicado en la dirección de memoria 0x40).
en el EVM Las 6 primeras palabras de la memoria se reservan y las 0x40-0x50 palabras de memoria se asignan al puntero de memoria libre.
Detalles: mload y mstore se definen en detalle en el documento amarillo:
[a...b) significa los bytes de memoria que comienzan en la posición a hasta (excluyendo) la posición b. sin embargo b] significa b incluido
Como han dicho otros, la x m:=mload(0x40)
instrucción lee los 32 bytes de memoria comenzando en la posición 0x40
.
En solidez, la 0x40
ranura en la memoria es especial: contiene el "puntero de memoria libre" que apunta al final de la memoria asignada actualmente.
Cuando usa el ensamblaje en línea, debe cargar los datos almacenados en 0x40
y luego solo escribir en las direcciones después del resultado. Cuando haya terminado, si desea mantener esa memoria asignada, debe sobrescribir 0x40
con el nuevo valor del puntero de memoria libre.
PUSH1 60 PUSH1 40 MSTORE
, pero ahora tiene sentido, 60
es el puntero de memoria libre.60
no 40
?Aquellos que puedan estar confundidos por la imagen publicada por @Badr, aunque no estoy seguro de por qué, la memoria no se parece actualmente (versión ^ 0.8.0). Como otros señalaron, las mload(0x40)
devoluciones donde el puntero se dirige a que puede comenzar a usarlo. (puntero libre)
Los primeros cuatro 32 bytes (128) siempre se reservan cuando se implementa su contrato inteligente. Esta es la razón por la que mload(0x40)
devuelve 80. 80 se representa en formato hexadecimal. ¡Es 128 en decimal, que es donde puede comenzar a escribir en la memoria! Así es como se ve la memoria actualmente.
tjaden hess
0x40
primero el puntero.Pablo Razvan Berg
Antón Cheng
Pablo Razvan Berg
Alex Lacayo
usuario1099123
Badr Bellaj
Rodrigo Herrera Itie