cpu
Различия
Показаны различия между двумя версиями страницы.
| Следующая версия | Предыдущая версия | ||
| cpu [2025/12/18 21:49] – создано gecko | cpu [2026/07/17 12:48] (текущий) – gecko | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| ====== CPU ====== | ====== CPU ====== | ||
| - | Процессором PlayStation является MIPS R3000, 32-битный RISC-микропроцессор, | + | Центральным процессором PlayStation является MIPS R3000, 32-битный RISC-микропроцессор, |
| ===== Регистры ===== | ===== Регистры ===== | ||
| Строка 13: | Строка 13: | ||
| * $26..$27 - k0..k1 - зарезервированы для [[BIOS]] | * $26..$27 - k0..k1 - зарезервированы для [[BIOS]] | ||
| * $28 - gp - [[global_pointer|глобальный указатель]] | * $28 - gp - [[global_pointer|глобальный указатель]] | ||
| - | * $29 - $sp - [[stack_pointer|стековый указатель]]. Содержит первый свободный адрес на стеке | + | * $29 - sp - [[stack_pointer|стековый указатель]]. Содержит первый свободный адрес на стеке |
| * $30 - fp/s8 - [[frame_pointer|указатель на фрейм]] | * $30 - fp/s8 - [[frame_pointer|указатель на фрейм]] | ||
| * $31 - ra - [[return_address|адрес возврата]]. Переход по этому адресу осуществляет возврат из процедуры. | * $31 - ra - [[return_address|адрес возврата]]. Переход по этому адресу осуществляет возврат из процедуры. | ||
| + | Особые регистры: | ||
| + | * hi, lo - результат целочисленного умножения/ | ||
| + | * pc - программный счетчик. | ||
| + | |||
| + | O32 ABI: | ||
| + | * $2..$3 (v0..v1) - возвратные значения | ||
| + | * $4..$7 (a0..a3) - аргументы | ||
| + | * $29 - указатель на стек | ||
| + | * $31 - адрес возврата. | ||
| + | |||
| + | Если функция использует более 4 32-битных аргументов, | ||
| + | |||
| + | ===== Инструкции ===== | ||
| + | |||
| + | **Арифметика: | ||
| + | * add $r, $a, $b - сложение. $r = $a + $b | ||
| + | * addu $r, $a, $b - беззнаковое сложение. $r = $a + $b | ||
| + | * addi $r, $a, imm - сложение с константой. $r = $a + imm | ||
| + | * addiu $r, $a, imm - беззнаковое сложение с константой. $r = $a + imm | ||
| + | * sub $r, $a, $b - вычитание. $r = $a - $b | ||
| + | * subu $r, $a, $b - беззнаковое вычитание. $r = $a - $b | ||
| + | * mult $a, $b - умножение. $a * $b | ||
| + | * multu $a, $b - беззнаковое умножение. $a * $b | ||
| + | * div $a, $b - деление. $a / $b | ||
| + | * divu $a, $b - беззнаковое деление. $a / $b | ||
| + | |||
| + | **Сравнение: | ||
| + | * slt $r, $a, $b - проверка условия " | ||
| + | * slti $r, $a, imm - проверка условия " | ||
| + | * sltiu $r, $a, imm - беззнаковая проверка условия " | ||
| + | |||
| + | **Побитовые операции: | ||
| + | * and $r, $a, $b - побитовое " | ||
| + | * andi $r, $a, imm - побитовое " | ||
| + | * or $r, $a, $b - побитовое " | ||
| + | * ori $r, $a, imm - побитовое " | ||
| + | * xor $r, $a, $b - исключающее " | ||
| + | * nor $r, $a, $b - отрицающее " | ||
| + | * sll $r, $a, imm - логический сдвиг влево на константное значение. $r = $a << imm | ||
| + | * sllv $r, $a, $b - логический сдвиг влево на переменное значение. Значение сдвига маскируется на 5 бит. $r = $a << ($b & 0x1f) | ||
| + | * slr $r, $a, imm - логический сдвиг вправо на константное значение. Верхние биты результата заполняются нулями. $r = $a >> imm | ||
| + | * srlv $r, $a, $b - логический сдвиг вправо на переменное значение. Верхние биты результата заполняются нулями. Значение сдвига маскируется на 5 бит. $r = $a >> ($b & 0x1f) | ||
| + | * sra $r, $a, imm - арифметический сдвиг вправо на константное значение. Верхние биты результата заполняются битом знака входного значения. $r = (int)$a >> imm | ||
| + | * srav $r, $a, $b - арифметический сдвиг вправо на переменное значение. Верхние биты результата заполняются битом знака входного значения. Значение сдвига маскируется на 5 бит. $r = (int)$a >> ($b & 0x1f) | ||
| + | |||
| + | **Чтение и запись памяти: | ||
| + | |||
| + | **Внимание!** Инструкции доступа к оперативной памяти требуют выровненные адреса. Доступ к слову (word) требует выравнивание по 4 байта, доступ к полуслову (half-word) требует выравнивание по 2 байта. Использование невыровненных адресов приведет к исключению шины. | ||
| + | |||
| + | * lw $r, imm($a) - загружает слово. $r = $a + imm | ||
| + | * lh $r, imm($a) - загружает полуслово. $r = $a + imm | ||
| + | * lhu $r, imm($a) - загружает беззнаковое полуслово. $r = $a + imm | ||
| + | * lb $r, imm($a) - загружает байт. $r = $a + imm | ||
| + | * lbu $r, imm($a) - загружает беззнаковый байт. $r = $a + imm | ||
| + | * lwl $r, imm($a) - загружает старшие байты слова по невыровненному адресу | ||
| + | * lwr $r, imm($a) - загружает младшие байты слова по невыровненному адресу | ||
| + | * sw $r, imm($a) - сохраняет слово. $a + imm = $r | ||
| + | * sh $r, imm($a) - сохраняет полуслово. $a + imm = $r | ||
| + | * sb $r, imm($a) - сохраняет байт. $a + imm = $r | ||
| + | * lui $r, imm` - загружает константу в старшие 16 бит слова | ||
| + | |||
| + | Инструкции загрузки не останавливают исполнение программы до тех пор, пока данные не будут доступны. Поэтому, | ||
| + | |||
| + | **Безусловный переход: | ||
| + | * j imm - безусловный переход по константному адресу | ||
| + | * jr $r - безусловный переход по переменному адресу | ||
| + | * jal imm - безусловный переход по константному адресу с сохранением адреса возврата в $31 | ||
| + | * jalr $r - безусловный переход по переменному адресу с сохранением адреса возврата в $31 | ||
| + | * jalr $r, $a - двухадресная форма jalr. Позволяет задать регистр для сохранения адреса возврата | ||
| + | |||
| + | **Условный переход (ветвление): | ||
| + | * beq $r, $a, imm - переход по константному адресу при равенстве операндов | ||
| + | * bne $r, $a, imm - переход по константному адресу при неравенстве операндов | ||
| + | * bgez $r, imm - переход по константному адресу, | ||
| + | * bltz $r, imm - переход по константному адресу, | ||
| + | * bgezal $r, imm - переход по константному адресу, | ||
| + | * bltzal $r, imm - переход по константному адресу, | ||
| + | |||
| + | **Псевдоинструкции: | ||
| + | |||
| + | * li $r, imm - загружает 32-битную константу. Если значение длиннее 16 бит, инструкция транслируется в lui и ori. Если значение умещается в 16 бит и не имеет знака, транслируется в ori. Если значение умещается в 16 бит и имеет знак, транслируется в addiu с нулевым первым операндом | ||
| + | * nop - то же самое, что sll $0, $0, 0 (такой вариант удобен тем, что в машинном коде выглядит как 0x00000000). Инструкция-филлер, | ||
cpu.1766094547.txt.gz · Последнее изменение: — gecko
