有人可以向我解释这个PHP代码吗? [关闭]

<?php
$registers = array(
    "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0",
    "s1", "s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
);
$typeR = array(
    "add" => 32, "sub" => 34, "sll" => 0, "srl" => 2, "and" => 36, "or" => 37, "xor" => 38, "slt" => 42, "mul" => 24,
    "div" => 26, "jr" => 8
);
$typeI = array(
    "addi" => 8, "lui" => 15, "andi" => 12, "ori" => 13, "xori" => 14, "slti" => 10, "beq" => 4, "bne" => 5, "lw" => 35,
    "sw" => 43
);
$typeJ = array(
    "j" => 2, "jal" => 3
);

function typeR($address, $rs, $rt, $rd, $registers, $shamt, $typeR, $opfunc)
{
    if ((empty($rd) || !ctype_digit($shamt)) && $opfunc != "jr") {
        return -1;
    }
    return array(
        "address" => $address,
        "bin" => "000000" . sprintf("%05d", decbin(array_search($rs, $registers)))
            . sprintf("%05d", decbin(array_search($rt, $registers)))
            . sprintf("%05d", decbin(array_search($rd, $registers)))
            . sprintf("%05d", decbin($shamt)) . sprintf("%06d", decbin($typeR[$opfunc]))
    );
}

function typeI($address, $rs, $rt, $imm, $registers, $typeI, $opfunc)
{
    $is_hex = strpos($imm, "x");
    $imm = $is_hex ? hexdec(substr($imm, $is_hex + 1)) : $imm;
    $imm = ($imm < 0) ? substr(decbin($imm), -16) : sprintf("%016b", $imm);
    return array(
        "address" => $address,
        "bin" => sprintf("%06d", decbin($typeI[$opfunc]))
            . sprintf("%05d", decbin(array_search($rs, $registers)))
            . sprintf("%05d", decbin(array_search($rt, $registers))) . $imm
    );
}

function typeJ($address, $addr, $typeJ, $opfunc)
{
    return array(
        "address" => $address,
        "bin" => sprintf("%06d", decbin($typeJ[$opfunc])) . sprintf("%026d", decbin($addr))
    );
}

function blankLines($string)
{
    $string = str_replace(array("\0", "\t", "", " ", "
"), "", $string);
    return (strlen($string) ? 1 : 0);
}

function findLabel($array, $arrayLen, $label)
{
    $label = $label . ":";
    for ($i = 0; $i < $arrayLen; $i++) {
        $array[$i] = explode(" ", $array[$i]);
        $subarrayLen = count($array[$i]);
        for ($j = 0; $j < $subarrayLen; $j++) {
            if (!strcmp($label, trim($array[$i][$j]))) {
                return ($i * 4);
            }
        }
    }
    return -1;
}

function comments($string)
{
    $commentI = ($string[0] == "#") ? -1 : strpos($string, "#");
    return (($commentI) ? substr($string, 0, $commentI - strlen($string)) : $string);
}

function format($array)
{
    $spaces = array("           ", "         ", "        ", "       ", "      ", "     ", "    ", "   ", "  ");
    $label = "";
    for ($i = 0; $i < count($array); $i++) {
        $array[$i] = str_replace(",", " ", $array[$i]);
        $array[$i] = @strtolower(trim(str_replace($spaces, " ", comments($array[$i]))));
        $inc = blankLines($array[$i]);
        $labelF = strpos($array[$i], ":");
        $instr = $labelF ? substr($array[$i], $labelF + 1) : $array[$i];
        if (!$inc || (!strlen($instr) && $i < (count($array) - 2))) {
            if (!strlen($instr) && $labelF) {
                $label = str_replace(array("\0", "\t", "", " ", "
"), "", $array[$i]);
            }
            unset($array[$i]);
            $array = array_values($array);
            $i--;
        } elseif (isset($label)) {
            $array[$i] = ($label . " " . trim($array[$i]));
            unset($label);
            $array = array_values($array);
        }
    }
    return $array;
}

function fileWrite($file, $instEnd, $count)
{
    $arrayLen = count($instEnd);
    for ($i = 0; $i < $arrayLen; $i++) {
        $instEnd[$i]["bin"] = substr($instEnd[$i]["bin"], -8, 8) . "+"
            . substr($instEnd[$i]["bin"], -16, 8) . "+"
            . substr($instEnd[$i]["bin"], -24, 8) . "+"
            . substr($instEnd[$i]["bin"], -32, 8);
        $instEnd[$i]["bin"] = explode("+", $instEnd[$i]["bin"]);
        $aux = 0;
        foreach ($instEnd[$i]["bin"] as $key => $value) {
            $instEnd[$i]["bin"][$key] = sprintf("%02X", bindec($value));
            $str = "0x" . sprintf("%03X", ($instEnd[$i]["address"] + $aux)) . " 0x" . $instEnd[$i]["bin"][$key];
            $str .= (((($count - 1) * 4) - 1) == (($i * 4) + $aux)) ? "\0" : "
";
            fwrite($file, $str);
            $aux++;
        }
    }
    echo "

Arquivo de saída gerado!

";
}

function assembler($arrayF, $typeR, $typeI, $typeJ, $registers, $argv)
{
    $fileOut = (!empty($argv[2])) ? $argv[2] : "memoria.mif";
    $file = fopen($fileOut, "w");
    if (!$file) {
        echo "
# Falha ao tentar criar o arquivo quickpatricia-eu.mif!
";
    }
    $instEnd = array();
    $arrayF = format($arrayF);
    $arrayLen = count($arrayF);
    $output = "";
    for ($i = 0; $i < $arrayLen; $i++) {
        $sub = array(",", "$");
        $address = ($i * 4);
        $labelF = strrpos($arrayF[$i], ":");
        $instr = $labelF ? substr($arrayF[$i], $labelF + 1) : $arrayF[$i];
        $instr = explode(" ", trim($instr));
        if (array_key_exists($instr[0], $typeR)) {
            if ($instr[0] == "sll" || $instr[0] == "srl") {
                $rd = trim(str_replace($sub, "", $instr[1]));
                $rt = trim(str_replace($sub, "", $instr[2]));
                $shamt = $instr[3] ? trim(str_replace($sub, "", $instr[3])) : 0;
                $rs = "0";
            } elseif ($instr[0] == "jr") {
                $rs = trim(str_replace($sub, "", $instr[1]));
                $rd = "0";
                $rt = "0";
                $shamt = "0";
            } else {
                $rd = trim(str_replace($sub, "", $instr[1]));
                $rs = trim(str_replace($sub, "", $instr[2]));
                $rt = $instr[3] ? trim(str_replace($sub, "", $instr[3])) : 0;
                $shamt = "0";
            }
            $return = typeR($address, $rs, $rt, $rd, $registers, $shamt, $typeR, $instr[0]);
            if ($return == -1) {
                $output .= "
A linha " . ($i + 1) . " possui algum erro.";
            } else {
                $instEnd[$i] = $return;
            }
        } elseif (array_key_exists($instr[0], $typeI)) {
            if (strpos($instr[2], "(")) {
                $begin = strpos($instr[2], "(");
                $end = strpos($instr[2], ")");
                $instr[3] = trim(substr($instr[2], $begin + 1, $end - strlen($instr[2])));
                $instr[2] = trim(substr($instr[2], 0, $begin));
                $imm = trim(str_replace($sub, "", $instr[2]));
                $rs = trim(str_replace($sub, "", $instr[3]));
                $rt = trim(str_replace($sub, "", $instr[1]));
            } elseif ($instr[0] == "lui") {
                $rs = "0";
                $rt = trim(str_replace($sub, "", $instr[1]));
                $imm = trim(str_replace($sub, "", $instr[2]));
            } elseif ($instr[0] == "bne" || $instr[0] == "beq") {
                $rs = trim(str_replace($sub, "", $instr[1]));
                $rt = trim(str_replace($sub, "", $instr[2]));
                $imm = trim(str_replace($sub, "", $instr[3]));
            } else {
                $rs = trim(str_replace($sub, "", $instr[2]));
                $imm = trim(str_replace($sub, "", $instr[3]));
                $rt = trim(str_replace($sub, "", $instr[1]));
            }
            $labelDef = (ctype_digit($imm) || $imm < 0) ? -1 : findLabel($arrayF, $arrayLen, $imm);
            if ($labelDef == -1) {
                $instEnd[$i] = typeI($address, $rs, $rt, $imm, $registers, $typeI, $instr[0]);
            } else {
                $instEnd[$i] = typeI($address, $rs, $rt, $labelDef, $registers, $typeI, $instr[0]);
            }
        } elseif (array_key_exists($instr[0], $typeJ)) {
            $addr = trim(str_replace($sub, "", $instr[1]));
            $labelDef = findLabel($arrayF, $arrayLen, $addr);
            if ($labelDef == -1) {
                $instEnd[$i] = typeJ($address, $addr, $typeJ, $instr[0]);
            } else {
                $instEnd[$i] = typeJ($address, $labelDef, $typeJ, $instr[0]);
            }
        } elseif (!$labelF) {
            $output .= "
A linha " . ($i + 1) . " não possui uma instrução válida!
";
        }
    }
    if ($output) {
        echo "


Erros:" . $output . "
";
    }else {
        fileWrite($file, $instEnd, $arrayLen);
    }
    fclose($file);
}
$arrayF = ($argv[1]) ? file($argv[1]) : 0;
if (!$arrayF) {
    echo "

# Arquivo de dados não foi especificado pelo usuário!

";
    exit(1);
}
assembler($arrayF, $typeR, $typeI, $typeJ, $registers, $argv);

This I found when I was looking for an assembly-to-mif "mounter". The problem is I know nothing of php (only a little of c and java)... can somebody please explain to me all tags and functions here, maybe do some analogies? I have to understand this code to make sure I see through every instruction conversion and can convert this code to java. Please, it would be a serious amount of help if some of you guys explained that.

Your question is a bit broad. If you have any specific things you would like answered, please let me know by commenting on this post. I'll start explaining a couple of things and see if that helps.

Regular Array

$registers = array(
    "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0",
    "s1", "s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
);

Associative Array (Map in Java)

$typeR = array(
    "add" => 32, "sub" => 34, "sll" => 0, "srl" => 2, "and" => 36, "or" => 37, "xor" => 38, "slt" => 42, "mul" => 24,
    "div" => 26, "jr" => 8
);

PHP Functions

You can look these up by googling the function name plus "php". They are defined on php.net. I'm sure many have Java equivalents.

Or better yet, get an IDE like Eclipse and hover over the functions to see their definitions. These are all PHP standard library functions.

  • empty - Checks if value is 0/null/empty array/etc.
  • ctype_digit - Checks if value is a number.
  • sprintf - return a formatted string
  • decbin - convert decimal to binary
  • array_search - checks an array for a value and returns the key
  • strpos - search for a string within a string, returns how many letters in the result is, or FALSE if not found
  • substr - Substring
  • explode - Split a string by string
  • count - Counts the # of values in an array
  • strcmp - Binary safe string compare

etc.