You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: evm_asm_builder.rs
    path of file: ./repos/sway/sway-core/src/asm_generation/evm
    
    the code of the file until where you have to start completion: use std::{collections::HashMap, sync::Arc};

use crate::{
    asm_generation::{
        asm_builder::{AsmBuilder, AsmBuilderResult},
        from_ir::StateAccessType,
        ProgramKind,
    },
    asm_lang::Label,
    metadata::MetadataManager,
};
use etk_ops::london::*;
use sway_error::{
    error::CompileError,
    handler::{ErrorEmitted, Handler},
};
use sway_ir::{Context, *};
use sway_types::Span;

use etk_asm::{asm::Assembler, ops::*};

/// A smart contract is created by sending a transaction with an empty "to" field.
/// When this is done, the Ethereum virtual machin
    
    fn setup_free_memory_pointer(&self, s: &mut EvmAsmSection) {
        // Setup the initial free memory pointer.
        //
        // The "free memory pointer" is stored at position 0x40 in memory.
        // The first 64 bytes of memory can be used as "scratch space" for short-term allocation.
        // The 32 bytes after the free memory pointer (i.e., starting at 0x60) are meant to be
        // zero permanently and is used as the initial value for empty dynamic memory arrays.
        // This means that the allocatable memory starts at 0x80, which is the initial value
        // of the free memory pointer.
        //
        //   push1 0x80
        //   push1 0x40
        //   mstore

        s.ops
            .push(AbstractOp::new(Op::Push1(Push1(Imm::with_expression(
                Expression::Terminal(0x80.into()),
            )))));
        s.ops
            .push(AbstractOp::new(Op::Push1(Push1(Imm::with_expression(
                Expression::Terminal(0x40.into()),
            )))));
        s.ops.push(AbstractOp::new(Op::MStore(MStore)));
    }