Архитектура ЭВМ и язык ассемблера

Представление об архитектуре ЭВМ

«ЭВМ вообще»


  • Калькулятор → хранение команд → хранение данных → атрибуция данных → подготовка и вывод результатов → выполнение команд в зависимости от данных → ЭВМ
    • Адресация и переходы как частные случаи
    ⇒ Архитектура фон Неймана исполнитель, память, В/В, коммутатор

Хранение данных и команд в памяти. ММ3

ММ3: условия и циклы

ММ2, ММ1, рассказ о ММ0

УМ-Р

Регистровая машина с модификацией адреса. Проход массива циклом.

Ассемблер. Язык ассемблера

Проблемы программирования в кодах: синтаксическое однообразие и отсутствие мнемоники

Ассемблер: текст→машинный язык; мнемоника команд; представление данных; метки. Проблема «второго прохода».

MIPS, базовые сведения об архитектуре и работе; простейшая программа

  1. Базовые сведения об архитектуре и работе.

    MARS-1.png

  2. MARS
    • Получение с сайта.Download Mars

    • Установка и запуск.
    • Настройка для первой программы.
      • В меню settings следует к настройкам по умолчанию добавить:
        • Assemble and execute programs using delayed branching = ON
        • Permit programs to use extended (pseudo) instructions and formats = OFF
    • Редактирование, ассемблирование, трассировка первой программы.
  3. Простейшая программа:

   1 ## AddSome.asm
   2 ##
   3 ## Program to demonstrate addition
   4 
   5         ori      $8, $0, 0xAB       # put 0x000000AB into $8
   6         ori      $9, $0, 0x55       # put 0x00000055 into $9
   7         addu     $10,$9, $8         # $10 <—— sum
   8 
   9 ## End of file

MIPS — архитектура и система команд

MIPS (англ. Microprocessor without Interlocked Pipeline Stages) — микропроцессор, разработанный компанией MIPS Computer Systems в соответствии с концепцией проектирования процессоров RISC.

  1. Схема

    MIPS_single_cycle.gif

  2. Цикл работы процессора
    • Загрузка инструкции (IF = Instruction Fetch)
    • Декодирование инструкции, выделение команды и операндов, чтение регистров (ID = Instruction Decode)
    • Фактическое выполнение инструкции (Ex = Execute)
    • Сохранение регистра в память, Загрузка регистра из памяти (MEM = Memory access)
    • Запись результата регистр (WB = Writeback)
    1.Микрокоманды и микропрограмма
    • Инструкция уровня языка ассемблера может быть разбита на отдельные микрокоманды. Программа интерпретирующая машинные инструкции называется микропрограммой. Микропрограмма позволяет на одном и том же наборе аппаратуры реализовать разные архитектуры.
  3. MIPS
    • 4GB оперативной памяти.
    • Инструкции одинаковой длины 32 бита.
    • 32 регистра общего назначения размером 32 бита.
    • Регистр $0 всегда возвращает 0.
    • Регистры PC, Hi, Lo.
  4. Типы и форматы инструкций.
    • Инструкции делятся на три типа: R, I и J. Каждая инструкция начинается с 6-битного кода. В дополнение к коду, инструкции R-типа определяют три регистра, область размера сдвига регистра, и область функции; инструкции I-типа определяют два регистра инепосредственное значение; инструкции J-типа состоят из кода операции и 26-битного адреса перехода.

    Тип

    −31− формат (в битах) −0−

    R

    код (6)

    rs (5)

    rt (5)

    rd (5)

    сдвиг (5)

    функция (6)

    I

    код (6)

    rs (5)

    rt (5)

    непосредственное значение (16)

    J

    код (6)

    адрес (26)

  5. Инструкции типов I и R.

    • Схема исполнения:

    MIPS-1_1.jpg

    • Арифметические:
      • add, addu, sub, subu, mult, multu, div, divu
      • addi, addiu
    • Логические:
      • and, or, xor, nor, slt
      • andi, ori, xori, slti
    • Сдвига:
      • sll, srl, sra
    • Передачи данных:
      • mfhi, mflo
  6. Пример программы:

   1 ## Program to assemble the instruction ori  $8,$9,0x004A
   2 ##
   3 
   4         or    $25,$0,$0        # clear $25
   5         ori   $11,$0,0xD       # opcode
   6         ori   $12,$0,0x9       # operand $s
   7         ori   $13,$0,0x8       # dest. $d
   8         ori   $14,$0,0x004A    # immediate operand
   9         
  10         sll   $11,$11,26       # shift opcode into position
  11         or    $25,$25,$11      # or it into the instruction
  12         
  13         sll   $12,$12,21       # shift operand $s into position
  14         or    $25,$25,$12      # or it into the instruction
  15         
  16         sll   $13,$13,16       # shift dest $d into position
  17         or    $25,$25,$13      # or it into the instruction
  18         
  19         or    $25,$25,$14      # or const into the instruction
  20         
  21         ori   $8,$9,0x004A     # The actual assembler
  22                                # should create the same machine
  23                                # instruction as we now have in $25
  24 
  25 ## end of file

   1 ## handMadeNeg.asm
   2 ## 
   3 ## Program to demonstrate two's complement negative
   4 ##
   5 ## The program adds +146 to -82, leaving the result in $10
   6 
   7         ori      $7, $0, 146        # put +146 into $7
   8         ori      $8, $0,  82        # put 82 into $8
   9         nor      $8, $8,  $0        # reflect
  10         ori      $9, $0,   1        # 
  11         addu     $8, $8,  $9        # add 1: $8 = -82
  12         addu    $10, $7,  $8        # (+146) + (-82)
  13 
  14 ## End of file

   1 ## Mult.asm
   2 ## 
   3 ## Program to calculate 5 * x - 74
   4 ##
   5 ## Register Use:
   6 ##  $8   x
   7 ##  $9   result
   8 ##
   9 ##  $10  5
  10 ##  $9,$10 result
  11 
  12         ori      $8, $0, 12        # put x into $8
  13         sll      $9, $8,  2        # $9 = 4x
  14         addu     $9, $9, $8        # $9 = 5x
  15         addiu    $9, $9,-74        # $9 = 5x - 74
  16 
  17         ori      $10, $0, 5        # $10 = 5
  18         multu     $8, $10
  19         mfhi     $9
  20         mflo     $10
  21         addiu    $10, $10, -74
  22         nop
  23 ## End of file

Адресация

индексация, SPIM: работа с байтами. Секции .text и .data

  1. Адресация.
    • Адресация — обращение к элементу данных по его адресу. Существует несколько способ интерпретации битов инструкции для указания местоположения данных:
    • Неявная адресация
    • Непосредственная
    • Прямая
    • Регистровая
    • Косвенная
    • Базовая
    • Относительная
    • Индексная
    • ...
  2. Секции(сегменты)
    • В программе принято отделять данные от кода. Секция есть непрерывный диапазон адресов, все данные в которых считаются с некоторой точки зрения однородными.
    • Некоторые процессоры аппаратно поддерживают подобное разделение.
    • Для определения секций в языке ассемблера MARS служат директивы: ".text" и ".data".
    • Ассемблер MARS не позволяет определять данные в секции .text.
      • директивы определения данных: ".word", ".half", ".byte", ".asciiz", ".ascii"
      • метки
      • точка входа, директива ".globl"
  3. Команды загрузки и сохранения:
    • lw, lh, lhu, lb, lbu
    • sw, sh, sb
    • lbu
    •    1 ## poly.asm -- complete program
         2 ##
         3 ## evaluate  5x^2 -12x + 97 
         4 ##
         5 ## Register Use:
         6 ##
         7 ## $10 base register, address of x
         8 ## $11 x
         9 ## $12 value of the polynomial
        10 ## $13 temporary
        11 
        12         .text
        13         .globl  main
        14 
        15 main: 
        16         lui   $10,0x1001     #  Init base register
        17         lw    $11,0($10)     #  Load x
        18 
        19         ori   $12,$0,97      #  Initialize the accumulator
        20                              #  during the "load delay slot"
        21 
        22         ori   $13,$0,12      #  evaluate second term
        23         mult  $11,$13        #  12x
        24         mflo  $13            #  assume 32 bit result
        25         subu  $12,$12,$13    #  accumulator = -12x +97
        26 
        27                              #  evaluate third term
        28         mult  $11,$11        #  x^2
        29         mflo  $11            #  assume 32 bit result
        30         ori   $13,$0,5       #  5
        31         mult  $11,$13        #  5x^2
        32         mflo  $13            #
        33         addu  $12,$12,$13    #  accumulator = 5x^2-12x+97
        34 
        35         sw    $12,4($10)     #  Store result in poly
        36 
        37         .data
        38 x:      .word   17           #  Edit this line to change the value of x
        39 poly:   .word   0            #  Result is placed here.
        40 
        41 ## End of file
      
  4. Команды перехода:
    • j, jr
    • beq, bne, bltz, bgez
    •    1 ##   $8  --- A, two's comp. integer
         2 ##   $9  --- sign bit of A
         3 ##   $10 --- base register for .data section
         4 
         5         .text
         6         .globl  main
         7 
         8 main: 
         9 # Get A
        10         lui   $10,0x1001     #  Init base register
        11         lw    $8,0($10)      #  Load A
        12         sll   $0,$0,0
        13 
        14 # Is A Negative?
        15         srl   $9,$8,31       #  Shift sign bit to position 0
        16         beq   $0,$9,done     #  sign bit == zero, done
        17         sll   $0,$0,0
        18 
        19 # Store -A
        20         subu  $8,$0,$8       #  negate A
        21         sw    $8,0($10)      #  save it
        22 
        23 done:   sll   $0,$0,0        #  target of the branch
        24 
        25         .data
        26 A:      .word  -14
        27 
        28 ## End of File
      
  5. Работа с байтами.
    •    1 ## endian.asm
         2 ##
         3 ## copy $9 to memory in big-endian order
         4 ##
         5 ## Register Use:
         6 ## $8  --- first byte of the tape buffer
         7 ## $9  --- 4-byte integer
         8 
         9       .text
        10       .globl  main
        11 
        12 main: 
        13       lui  $9,0x1234      # put data in $9
        14       ori  $9, $9, 0x5678      #
        15       lui  $8,0x1001      # $8 is base register
        16       sb   $9,3($8)       # least significant byte
        17       srl  $9,$9,8        # move next byte to low order
        18       sb   $9,2($8)       # bits 8-15 
        19       srl  $9,$9,8        # move next byte to low order
        20       sb   $9,1($8)       # bits 16-23 
        21       srl  $9,$9,8        # move next byte to low order
        22       sb   $9,0($8)       # most significant byte
        23 
        24       .data
        25 tape:                     # base register points here
        26       .space 1024         # tape buffer (1K bytes)
        27          
      
  6. Массивы.
    •    1 ## addIntArray.asm
         2 ##
         3 ## Sum all integers, the positive integers,
         4 ## and the negative integers in an array.
         5 
         6 ## Registers:
         7 ##  $8 -- count
         8 ##  $9 -- pointer to the array entry
         9 ## $10 -- current array entry
        10 ## $11 -- sum of all integers
        11 ## $12 -- sum of negative integers
        12 ## $13 -- sum of positive integers
        13 ## $14 -- pos. or neg. flag
        14 ## $15 -- length of the array
        15 
        16          .text
        17          .globl  main
        18 # Initialize
        19 main:    ori      $8,$0,0        #  count = 0
        20          ori      $11,$0,0       #  sum = 0
        21          ori      $12,$0,0       #  neg = 0
        22          ori      $13,$0,0       #  pos = 0
        23          lui      $9,0x1001      #  point at SIZE
        24 
        25          lw       $15,0($9)      #  get SIZE
        26          addiu    $9,$9,4        #  point to first entry
        27 
        28 # while  count < SIZE do
        29 loop:    beq      $8,$15,done 
        30          sll      $0,$0,0        #  branch delay
        31 
        32 # get entry, add to sum
        33          lw       $10,0($9)      #  get entry
        34          sll      $0,$0,0        #  load delay
        35          addu     $11,$11,$10    #  add to sum
        36 
        37 #  test neg. or pos.
        38          slti     $14,$10,0x0    #  set $14 if entry is neg
        39          bne      $14,$0,neg     #  branch if negative
        40          sll      $0,$0,0        #  branch delay
        41          addu     $13,$13,$10    #  positive: add to PLUS
        42          j        ifend
        43          sll      $0,$0,0        #  branch delay
        44 
        45 neg:     addu     $12,$12,$10    #  negative: add to NEG
        46 
        47 ifend:   addiu    $8,$8,1        # count++
        48          addiu    $9,$9,4        # point at next entry
        49          j        loop
        50          sll      $0,$0,0        #  branch delay
        51 
        52 # finish
        53 done:    sll      $0,$0,0        # target for branch
        54 
        55         .data
        56 size:   .word  4
        57 array:  .word  1, 2, -2, -1
      
  7. Аресация MIPS:

addr.png

Взаимодействие процессор-память

В современном компьютере можно выделить несколько функционально различных блоков: процессор, основная память, внешние запоминающие устройства, ...(более того, эти блоки обладают внутренней сложной структурой).

  1. Шина — подсистема, служащая для передачи данных между функциональными блоками компьютера.
  2. Протокол шины.
  3. Шины адреса и данных. Гарвард/Принстон.
  4. Организация микросхем основной памяти. Цикл чтения/записи. Длительность цикла чтения/записи в циклах шины/процессора.
  5. Идея кэширования.
  6. Виды памяти:
    • SRAM — быстрая и дорогая:
      • Регистры
      • Кэш
    • DRAM — медленная и не дорогая:
      • Основная память
    • Прочее SSD, HDD,... — энергонезависимая:
      • Внешние запоминающие устройства.
  7. Пирамида задержек.
    • [ПРИКРЕПЛЁННЫЙ ФАЙЛ]

  8. Методы повышения производительности подсистемы памяти
    • Буферизация.
    • перекрытие циклов(конвейер).
    • расщеплении(параллелизм)
  9. Постоянные программируемые запоминающие устройства с произвольным доступом(ROM). Использование ROM для первоначальной инициализации компьютера.

Конвенции, псевдоинструкции и макросы

Структура памяти, псевдоинструкции, макросы, понятие о конвенциях ().

  1. Конвенции.
  2. Расширенный ассемблер.
    • Ассемблер MIPS предоставляет псевдокоманды, которые на самом деле не являются частью набора команд, но часто используются программистами и компиляторами. При преобразовании в машинный код псевдокоманды транслируются в одну или несколько команд MIPS. Некоторым псевдокомандам требуется временный регистр для промежуточных вычислений. Ассемблер использует для этих целей временный регистр $at.
    • именование и использование регистров

Название

Номер

Назначение

$zero

0

Константный нуль

$at

1

Временный регистр для нужд ассемблера

$v0–$v1

2-3

Возвращаемые функциями значения

$a0–$a3

4-7

Аргументы функций

$t0–$t7

8-15

Временные переменные

$s0–$s7

16-23

Сохраняемые переменные

$t8–$t9

24-25

Временные переменные

$k0–$k1

26-27

Временные переменные операционной системы (ОС)

$gp

28

Глобальный указатель (англ.: global pointer)

$sp

29

Указатель стека (англ.: stack pointer)

$fp

30

Указатель кадра стека (англ.: frame pointer)

$ra

31

Регистр адреса возврата из функции

  • псевдоинструкции:
    • move, li, la, lw, sw, nop
    • not, abs, addu, subu, negu, mul, div, divu, remu, rol, ror
    • seq, sge, sgeu, sgt, sgtu, sle, sleu, slt, slti, sltu, sltiu, sne
    • b, beq, beqz, bge, bgeu, bgez, bgt,bgtu, bgtz, ble, bleu, blez, blt, bltu, bltz, bnez, bne
    • syscall
  • примеры:

   1 ## pseudoPoly.asm
   2 ## evaluate the polynomial ax2 + bx + c
   3 ##
   4         .text
   5         .globl  main
   6 
   7 main:
   8         lw   $t3,x          # get x
   9         lw   $t0,a          # get a
  10         lw   $t1,bb         # get bb
  11         lw   $t2,c          # get c
  12 
  13         mult $t3,$t3        # x2
  14         mflo $t4            # $t4 = x2
  15         nop
  16         nop
  17         mult $t4,$t0        # low  = ax2
  18         mflo $t4            # $t4  = ax2
  19         nop
  20         nop
  21 
  22         mult $t1,$t3        # low  = bx
  23         mflo $t5            # $t5  = bx
  24         addu $t5,$t4,$t5    # $t5  = ax2 + bx
  25 
  26         addu $t5,$t5,$t2    # $t5 = ax2 + bx + c
  27         sw   $t5,value      # value = polynomial
  28 
  29         .data
  30 x:      .word   4 
  31 value:  .word   1 
  32 a:      .word  20
  33 bb:     .word  -2           # the SPIM assembler does not allow the label "b"
  34 c:      .word   5
  35  
  1. Макроподстановки

Стек и подпрограммы

  1. Стек:
    • Стек
    • Стек MIPS
      • 0x7FFF FFFF
      • растет вниз
    • Регистр указателя стека
      •    1 # Evaluate the expression ab - 12a + 18b - 7
           2 #
           3 # Settings: Load delays OFF; Branch delays OFF,
           4 #           Trap file    ON; Pseudoinstructions ON
           5 
           6         .globl  main
           7 
           8 main:
           9         lw      $t0,a          # get a
          10         lw      $t1,bb         # get b
          11         mul     $t0,$t0,$t1    # a*b
          12         subu    $sp,$sp,4      # push a*b onto stack
          13         sw      $t0,($sp)
          14 
          15         lw      $t0,a          # get a
          16         li      $t1,-12        #
          17         mul     $t0,$t0,$t1    # -12a
          18         subu    $sp,$sp,4      # push -12a onto stack
          19         sw      $t0,($sp)
          20 
          21         lw      $t0,bb         # get b
          22         li      $t1,18         #
          23         mul     $t0,$t0,$t1    # 18b
          24         subu    $sp,$sp,4      # push 18b onto stack
          25         sw      $t0,($sp)
          26 
          27         li      $t1,-7         # init sum to -7
          28         lw      $t0,($sp)      # pop 18b
          29         addu    $sp,$sp,4
          30         addu    $t1,$t1,$t0    # 18b -7
          31 
          32         lw      $t0,($sp)      # pop -12a
          33         addu    $sp,$sp,4
          34         addu    $t1,$t1,$t0    # -12a + 18b -7
          35 
          36         lw      $t0,($sp)      # pop ab
          37         addu    $sp,$sp,4
          38         addu    $t1,$t1,$t0    # ab - 12a + 18b -7
          39 
          40 done:   li      $v0,1          # print sum
          41         move    $a0,$t1
          42         syscall
          43         li      $v0,10         # exit
          44         syscall
          45 
          46         .data
          47 a:      .word  0
          48 bb:     .word  10
        
    • Аппаратный стек
  2. Подпрограммы:
    • повторное использование
    • модульность
    • проблема возврата
    • аппаратная поддержка:
      • инструкции - "jal" и "jr"("jalr")
      • особая роль регистра $31($ra)
  3. Конвенции о вызове:
    • вызывающий и и вызываемый
    • правила сохранения и использования регистров
  4. Простая конечная подпрограмма:
    • Простая конвенция о вызове:
      1. Подпрограмма вызывается с помощью инструкции "jal"(которая сохранит обратный адрес в регистре $ra).
      2. Подпрограмма не будет вызывать другую подпрограмму(конечная).
      3. Подпрограмма возвращает управление вызывающей программе с помощью инструкции "jr $rа".
      4. Регистры используются следующим образом:
        • $t0 - $t9 - подпрограмма может изменить эти регистры.
        • $s0 - $s7 - подпрограмма не должны изменять эти регистры.
        • $а0 - $a3 - эти регистры содержат аргументы для подпрограммы. Подпрограмма может изменить их.
        • $v0 - $v1 - эти регистры содержат значения, возвращаемые из подпрограммы.
      5. Основная программа возвращает управление с помощью системного вызова(syscall) 10.
       1 # addthree.asm --- read in three integers and print their sum
       2 #
       3 # This program uses simple linkage.
       4 #
       5 # Settings: Load delays  ON;  Branch delays ON
       6 #           Trap file    ON;  Pseudoinstructions ON
       7 #
       8 
       9          .text
      10          .globl  main
      11 main:
      12          jal     pread            # read first integer
      13          nop                      #
      14          move    $s0,$v0          # save it in $s0
      15 
      16          jal     pread            # read second integer
      17          nop                      #
      18          move    $s1,$v0          # save it in $s1
      19 
      20          jal     pread            # read third integer
      21          nop                      #
      22          move    $s2,$v0          # save it in $s2
      23 
      24          addu    $s0,$s0,$s1      # compute the sum
      25          addu    $a0,$s0,$s2
      26 
      27          li      $v0,1            # print the sum
      28          syscall
      29 
      30          li      $v0,10           # exit
      31          syscall
      32 
      33 
      34 # pread -- prompt for and read an integer
      35 #
      36 # on entry:
      37 #    $ra -- return address
      38 #
      39 # on exit:
      40 #    $v0 -- the integer
      41 
      42          .text
      43          .globl  pread
      44 pread:
      45          la    $a0,prompt        # print string
      46          li    $v0,4             # service 4
      47          syscall
      48 
      49          li    $v0,5             # read int into $v0
      50          syscall                 # service 5
      51 
      52          jr    $ra               # return
      53          nop                     #
      54 
      55          .data
      56 prompt:
      57          .asciiz "Enter an integer: "
    

Фреймы, локальные переменные, рекурсия

Ранее рассмотренная конвенция не обеспечивает некоторые возможности языков высокого уровня. Добавим некоторые из этих функций в новой конвенции о вызове процедур на основе стека.

  1. Сохранение регистров в стеке
    • Сохранение адреса возврата в стеке($ra)
    • Сохранение и восстановление регистров $s0―$s7 в/из стеке/стека
  2. Конвенция о вызове процедур на основе стека.
    • Это не официальное соглашение. Однако, оно может быть использовано для небольшого проекта на языке ассемблера. Конвенция не очень сложна и делает почти все, что может быть нужно. Если вы хотите использовать процедуры из программы на языке "C", использовать процедуры из библиотек, написанных на других ЯП или вызывать вашу процедуру из программы на ЯВУ, то необходимо использовать официальные правила в полном объеме. (Что в эмуляторе MARS невозможно.)
    • Правила:
      1. Вызов подпрограммы (делает вызывающая процедура):
        • Сохранить в стеке регистры "$t0 - $t9", которые должны быть сохранены(будут использованы вызывающей процедурой после вызова подпрограммы). Подпрограмма может изменить эти регистры.
        • Загрузить значения аргументов в регистры "$a0 - $a3".
        • Вызов подпрограммы с помощью "jal".
      2. Пролог подпрограммы:
        • Сохранить регистр "$ra" в стек.
        • Сохранить в стек регистры "$s0 - $s7"(подпрограмма может изменять их).
      3. Тело подпрограммы:
        • Подпрограмма может изменять регистры "$t0 - $t9", или те из регистров "$s0 - $s7", которые были сохранены в прологе.
        • Из подпрограммы можно вызывать другую подпрограмму, следуя этим правилам.
      4. Эпилог подпрограммы (непосредственно перед возвращением):
        • Загрузить возвращаемые значения в регистры "$v0 - $v1".
        • Извлечь из стека (в обратном порядке) сохраненые в прологе регистры "$s0 - $s7".
        • Извлечь из стека в регистр '$ra" адрес возврата.
        • Вернуться в вызывающую процедуру, используя "jr $ra".
      5. Восстановление состояния при выходе из подпрограммы:
        • Извлечь из стека (в обратном порядке) сохраненые регистры "$t0 - $t9".
  3. Пролог и эпилог вызываемой подпрограммы:
  4. Вызов и возврат.
  5. Вложенные вызовы подпрограмм и цепь активации.
  6. О реальных конвенциях(ABI).
  7. Пример программы:
    •    1 ## Driver --  main program for the application
         2 
         3          .text
         4          .globl main
         5  
         6 main:
         7          sub     $sp,$sp,4        # push the return address
         8          sw      $ra,($sp)
         9          sub     $sp,$sp,4        # push $s0
        10          sw      $s0,($sp)
        11          
        12          la      $a0,xprompt      # prompt the user
        13          li      $v0,4            # service 4
        14          syscall
        15          li      $v0,5            # service 5 -- read int
        16          syscall                  # $v0 = integer
        17          move    $s0,$v0          # save x
        18          
        19          la      $a0,yprompt      # prompt the user
        20          li      $v0,4            # service 4
        21          syscall
        22          li      $v0,5            # service 5 -- read int
        23          syscall                  # $v0 = integer
        24          
        25                                   # prepare arguments
        26          move    $a0,$s0          # x         
        27          move    $a1,$v0          # y
        28          jal     maxExp           # maximum expression
        29          nop                      # returned in $v0
        30          move    $s0,$v0          # keep it safe
        31 
        32          la      $a0,rprompt      # output title
        33          li      $v0,4            # service 4
        34          syscall
        35 
        36          move    $a0,$s0          # get maximum
        37          li      $v0,1            # print it out
        38          syscall
        39                                                       
        40          lw      $ra,($sp)        # pop $s0
        41          add     $s0,$sp,4
        42          lw      $ra,($sp)        # pop return address
        43          add     $sp,$sp,4
        44          
        45          li      $s0,0              # return to OS
        46          li      $v0,10
        47          syscall
        48          
        49          
        50          .data
        51 xprompt: .asciiz  "Enter a value for x --> "
        52 yprompt: .asciiz  "Enter a value for y --> "
        53 rprompt: .asciiz  "The maximum expression is: "
        54 
        55 ## maxInt -- compute the maximum of two integer arguments
        56 ##
        57 ## Input:
        58 ## $a0 -- a signed integer
        59 ## $a1 -- a signed integer
        60 ##
        61 ## Returns:
        62 ## $v0 -- maximum
        63 
        64          .text
        65          .globl maxInt
        66 
        67 maxInt:
        68          # body
        69          move   $v0,$a0          # max = $a0
        70          bgt    $a0,$a1,endif    # if $a1 > $a0  
        71          nop
        72          move   $v0,$a1          #    max = $a1
        73 endif:                           # endif 
        74          # epilog
        75          jr     $ra              # return to caller
        76          nop
        77           
        78 ## maxExp -- compute the maximum of three expressions
        79 ##
        80 ## Input:
        81 ## $a0 -- a signed integer, x
        82 ## $a1 -- a signed integer, y
        83 ##           
        84 ## Returns: 
        85 ## $v0 -- the maximum of x*x,  x*y, or 5*y
        86 ##
        87 ## Registers:
        88 ## $s0 --  x*x
        89 ## $s1 --  x*y
        90 ## $s2 --  5*y
        91 
        92          .text
        93          .globl maxExp
        94 
        95 maxExp:
        96          # prolog
        97          sub     $sp,$sp,4        # push the return address
        98          sw      $ra,($sp)
        99          sub     $sp,$sp,4        # push $s0
       100          sw      $s0,($sp)
       101          sub     $sp,$sp,4        # push $s1
       102          sw      $s1,($sp)
       103          sub     $sp,$sp,4        # push $s2
       104          sw      $s2,($sp)
       105 
       106          # body
       107          mul     $s0,$a0,$a0      # x*x
       108          mul     $s1,$a0,$a1      # x*y
       109          li      $t0,5
       110          mul     $s2,$t0,$a1      # 5*y
       111          
       112          move    $a0,$s0          # compute max of x*x
       113          move    $a1,$s1          # and x*y
       114          jal     maxInt           # current max in $v0
       115          nop
       116 
       117          move    $a0,$v0          # compute max of
       118          move    $a1,$s2          # current max, and 5*y 
       119          jal     maxInt           # total max will be in $v0
       120          nop
       121          
       122          # epilog
       123          lw      $s2,($sp)        # pop $s2 
       124          add     $sp,$sp,4                                    
       125          lw      $s1,($sp)        # pop $s1 
       126          add     $sp,$sp,4                                    
       127          lw      $s0,($sp)        # pop $s0 
       128          add     $sp,$sp,4                                    
       129          lw      $ra,($sp)        # pop return address
       130          add     $sp,$sp,4         
       131          jr      $ra              # return to caller 
       132          nop         
      
  8. Локальные переменные.
  9. Кадр стека.
  10. Конвенция о вызове процедур с использованием указателя кадра стека.
    • Это не официальное соглашение. В большинстве реальных MIPS-ABI использование указателя кадра стека факультативно. В широко распространенной архитектуре "intel32/64" указателя кадра стека активно используется.
    1. Вызов подпрограммы (делает вызывающая процедура):
      • Сохранить в стеке регистры "$t0 - $t9", которые должны быть сохранены(будут использованы вызывающей процедурой после вызова подпрограммы). Подпрограмма может изменить эти регистры.
      • Загрузить значения аргументов в регистры "$a0 - $a3".
      • Вызов подпрограммы с помощью "jal".
    2. Пролог подпрограммы:
      • Сохранить регистр "$ra" в стек.
      • Сохранить регистр "$fp" в стек.
      • Сохранить в стек регистры "$s0 - $s7"(подпрограмма может изменять их).
      • Инициализировать указатель кадра: $fp = ($sp - размер пространства для локальных переменных).
        • NB Помните, что вычитание из $sp увеличивает стек, что стек растет вниз, что размер переменной всегда четыре байта.

      • Инициализировать указателя стека: $sp = $fp.
    3. Тело подпрограммы:
      • Подпрограмма может изменять регистры "$t0 - $t9", или те из регистров "$s0 - $s7", которые были сохранены в прологе.
      • Из подпрограммы можно вызывать другую подпрограмму, следуя этим правилам.
      • Подпрограмма обращается к локальным переменным, как disp($fp).
      • Подпрограмма может работать со стеком, используя регистр "$sp".
    4. Эпилог подпрограммы (непосредственно перед возвращением):
      • Загрузить возвращаемые значения в регистры "$v0 - $v1".
      • $sp = ($fp + размер пространства для локальных переменных).
      • Извлечь из стека (в обратном порядке) сохраненные в прологе регистры "$s0 - $s7".
      • Извлечь из стека в регистр "$fp" адрес кадра стека.
      • Извлечь из стека в регистр '$ra" адрес возврата.
      • Вернуться в вызывающую процедуру, используя "jr $ra".
    5. Восстановление состояния при выходе из подпрограммы (делает вызывающая процедура):
      • Извлечь из стека (в обратном порядке) сохраненые регистры "$t0 - $t9".
  11. Пример программы:
       1 ## file variablesStack.asm
       2 
       3 #  int mysub( int arg )
       4 #  {
       5 #    int b,c;                     // b: 0($fp)
       6 #                                 // c: 4($fp)
       7 #    b = arg*2;
       8 #    c = b + 7;
       9 #    
      10 #    return c;  
      11 #  }
      12          .text
      13          .globl  mysub
      14 mysub:
      15                                   # prolog        
      16          sub     $sp,$sp,4        #   1. Push return address
      17          sw      $ra,($sp)
      18          sub     $sp,$sp,4        #   2. Push caller's frame pointer
      19          sw      $fp,($sp)
      20          sub     $sp,$sp,4        #   3. Push register $s1
      21          sw      $s1,($sp)
      22          sub     $fp,$sp,8        #   4. $fp = $sp - space_for_variables
      23          move    $sp,$fp          #   5. $sp = $fp
      24          
      25                                   # body of subroutine     
      26          mul     $s1,$a0,2        #     arg*2
      27          sw      $s1,0($fp)       # b = "   "
      28          
      29          lw      $t0,0($fp)       # get b
      30          add     $t0,$t0,7        #     b+7
      31          sw      $t0,4($fp)       # c = "  "
      32          
      33                                   # epilog
      34          lw      $v0,4($fp)       #   1. Put return value in $v0        
      35          add     $sp,$fp,8        #   2. $sp = $fp + space_for_variables
      36          lw      $s1,($sp)        #   3. Pop register $s1
      37          add     $sp,$sp,4        #          
      38          lw      $fp,($sp)        #   4. Pop $fp
      39          add     $sp,$sp,4        #           
      40          lw      $ra,($sp)        #   5. Pop $ra
      41          add     $sp,$sp,4        #            
      42          jr      $ra              #   6. return to caller 
      43 
      44 #  main()
      45 #  {
      46 #    int a;                      // a: 0($fp)
      47 #    a = mysub( 6 );
      48 #    print( a );
      49 #  }
      50          .text
      51          .globl  main
      52 main:
      53                                   # prolog        
      54          sub     $sp,$sp,4        #   1. Push return address
      55          sw      $ra,($sp)
      56          sub     $sp,$sp,4        #   2. Push caller's frame pointer
      57          sw      $fp,($sp)
      58                                   #   3. No S registers to push
      59          sub     $fp,$sp,4        #   4. $fp = $sp - space_for_variables
      60          move    $sp,$fp          #   5. $sp = $fp
      61 
      62                                   # subroutine call
      63                                   #   1. No T registers to push
      64          li      $a0,6            #   2. Put argument into $a0
      65          jal     mysub            #   3. Jump and link to subroutine
      66          
      67                                   # return from subroutine 
      68                                   #   1. No T registers to restore
      69                                   
      70          sw     $v0,0($fp)        # a = mysub( 6 )
      71         
      72                                   # print a
      73          lw     $a0,0($fp)        # load a into $a0
      74          li     $v0,1             # print integer service
      75          syscall                                  
      76                                   # epilog
      77                                   #   1. No return value         
      78          add     $sp,$fp,4        #   2. $sp = $fp + space_for_variables       
      79                                   #   3. No S registers to pop      
      80          lw      $fp,($sp)        #   4. Pop $fp
      81          add     $sp,$sp,4        #           
      82          lw      $ra,($sp)        #   5. Pop $ra
      83          add     $sp,$sp,4        #                                    
      84 
      85          li      $s0,0              # return to OS
      86          li      $v0,10
      87          syscall
    
  12. Приложения:
    • MIPS ABI

    MIPS ABI History

    MIPS ABIs Described

    SYSTEM V APPLICATION BINARY INTERFACE

    MIPSpro TM N32 ABI Handbook

    mips eabi documentation...

Взаимодействие с ОС

Задачи операционной системы (унификация, разделение и учёт ресурсов компьютера)

"операционная система Совокупность системных программ, предназначенная для обеспечения определенного уровня эффективности системы обработки информации за счет автоматизированного управления ее работой и предоставляемого пользователю определенного набора услуг." ГОСТ 15971-90

"Операционная система — это программа, которая добавляет ряд команд и особенностей к тем, которые обеспечиваются уровнем команд. Обычно операционная система реализуется главным образом в программном обеспечении, но нет никаких веских причин, по которым ее нельзя было бы реализовать в аппаратном обеспечении (как микропрограммы)." (А.Таненбаум, курсив мой ali) Пожелания к ОС:

  • Унификация
  • Защита

Аппаратные требования(желательные):

  • Защита. Режимы работы процессора(полный и ограниченный)
  • Двойной поток вычислений.(исключения)
  • Менеджмент памяти

Использование возможностей ОС: syscall

SYSCALL functions available in MARS

Примеры sysall-ов (в первую очередь В/В)

Примеры программирования для ОС

Соответствующие конвенции.

Понятие о сопроцессорах. FPU

  1. Сопроцессоры:
    • Сопроцессор 1 - FPU
    • Сопроцессор 0 - управления
  2. Стандарт IEEE 754
    • Mars -> Tools -> Floating Point Representation

  3. FPU MIPS
    1. MIPS поддерживает числа с плавающей точкой одинарной и двойной точности в IEEE-формате.
    2. Архитектура MIPS предусматривает наличие тридцати двух 32-битных регистров для чисел с плавающей точкой "$f0–$f31". Это не те же самые регистры, которые мы использовали до сих пор.
    3. Числа двойной точности (64-битные) размещаются в парах 32-битных регистров, так что для операций с такими числами доступны только 16 четных регистров "$f0, $f2, $f4, ..., $f30".
    4. В соответствии с соглашением, принятым в архитектуре MIPS, у этих регистров разное назначение:
      • Название

        Номер

        Назначение

        $fv0–$fv1

        0, 2

        Значение, возвращаемое функцией

        $ft0–$ft3

        4, 6, 8, 10

        Временные переменные

        $fa0–$fa1

        12, 14

        Аргументы функции

        $ft4–$ft5

        16, 18

        Временные переменные

        $fs0–$fs5

        20, 22, 24, 26, 28, 30

        Сохраняемые переменные

    5. Код операции у всех команд с плавающей точкой равен 17 (10001 2 ). Для определения типа команды в них должны присутствовать поля funct и cop (от англ. coprocessor). Ниже показан формат команд типа F, используемый для чисел с плавающей точкой.
      • op

        cop

        ft

        fs

        fd

        funct

        6bits

        5bits

        5bits

        5bits

        5bits

        6bits

      Поле cop равно 16 (10000 2 ) для команд одинарной точности и 17 (10001 2 ) для команд двойной точности. Аналогично командам типа R, у команд типа F есть два операнда-источника (fs и ft) и один операнд-назначение (fd). Формат команд типа F
    6. Команды одинарной и двойной точности различаются суффиксом в мнемонике (.s и .d соответственно). Команды с плавающей точкой включают сложение (add.s, add.d), вычитание (sub.s, sub.d), умножение (mul.s, mul.d), деление (div.s, div.d), изменение знака (neg.s, neg.d) и вычисление модуля (abs.s, abs.d).
    7. Регистры с плавающей точкой загружаются из памяти и записываются в память при помощи команд lwc1 и swc1 соответственно. Эти команды перемещают по 32 бита, так что для работы с числами двойной точности необходимо использовать по две такие команды.
    8. В тех случаях, когда ветвление зависит от условия, вычисляемого с использованием чисел с плавающей точкой, оно делится на две части. Сначала команда сравнения устанавливает или сбрасывает специальный флаг условия fpcond (от англ. floating point condition flag, флаг "0" "Coproc 1" в Mars). После этого команда ветвления проверяет этот флаг и в зависимости от его состояния осуществляет переход. Команды сравнения включают команды проверки на равенство (c.seq.s/c.seq.d), проверки на то, что один операнд меньше другого (c.lt.s/c.lt.d) или меньше или равен другому (c.le.s/c.le.d). Команды ветвления bc1f и bc1t осуществляют переход, если флаг fpcond имеет значение ЛОЖЬ или ИСТИНА соответственно. Другие варианты сравнений, такие как проверка на неравенство или на то, что один операнд больше другого, или больше или равен другому, осуществляются при помощи команд с суффиксами seq, lt, le и последующей командой bc1f.
  4. Пример. Использованы инструкции расширенного языка ассемблера.

   1 ## newton.asm -- compute sqrt(n) 
   2 
   3 ## given an approximation x to sqrt(n),
   4 ## an improved approximation is:
   5 
   6 ## x' = (1/2)(x + n/x)
   7 
   8 ## $f0  ---  n
   9 ## $f1  ---  1.0
  10 ## $f2  ---  2.0
  11 ## $f3  ---  x  : current approx.
  12 ## $f4  ---  x' : next approx.
  13 ## $f8  ---  temp
  14 
  15         .text
  16         .globl main
  17 
  18 main:   
  19 
  20         l.s     $f0,n               # get n
  21         l.s     $f1,con_1           # constant 1.0
  22         l.s     $f2,con_2           # constant 2.0
  23         l.s     $f3,con_1           # x == first approx.
  24         l.s     $f10,ep             # five figure accuracy
  25                 
  26 loop:   
  27         mov.s   $f4,$f0             # x' = n
  28         div.s   $f4,$f4,$f3         # x' = n/x
  29         add.s   $f4,$f3,$f4         # x' = x + n/x
  30         div.s   $f3,$f4,$f2         # x    = (1/2)(x + n/x)
  31 
  32         mul.s   $f8,$f3,$f3         # x^2
  33         div.s   $f8,$f0,$f8         # n/x^2
  34         sub.s   $f8,$f8,$f1         # n/x^2 - 1.0
  35         abs.s   $f8,$f8             # |n/x^2 - 1.0|
  36         c.lt.s  $f8,$f10            # |x^2 - n| < small ?
  37         bc1t    done                # yes: done
  38   
  39         j       loop                # next approximation
  40         
  41 done:
  42         mov.s   $f12,$f3            # print the result
  43         li      $v0,2
  44         syscall
  45  
  46         li      $a0,0
  47         li      $v0,10              # return to OS
  48         syscall
  49 ##
  50 ##  Data Segment  
  51 ##
  52         .data
  53 n:      .float  4.0
  54 ep:     .float  1.0e-5
  55 con_1:  .float  1.0
  56 con_2:  .float  2.0

Исключения и системные вызовы

  1. Исключения - события, которые, помимо условных и безусловных переходов, изменяют нормальный порядок исполнения инструкций.
    • NB Терминология не устоялась. Так intel использует только термин "прерывание". В традиции mips(risc) принято использовать термин "исключение" для обозначения любого неожиданного изменения в алгоритме управления. Термин "прерывание" будет использоваться только для обозначения внешних событий.

  2. Возможная классификация:
    • Тип события

      Источник

      Термин MIPS

      Переполнение

      Внутренний

      Исключение

      Нет инструкции

      Внутренний

      Исключение

      Системный вызов

      Внутренний

      Исключение

      Запрос внешнего устройства

      Внешний

      Прерывание

      Отказ оборудования

      Внутренний/Внешний

      Исключение/Прерывание

  3. Общая идея обработки исключения.
    • Аппаратура процессора обнаруживает исключения и осуществляет передачу управления.
      • переход на фиксированный адрес
      • вектор прерываний
    • Программная обработка
    • Возврат к нормальному порядку исполнения инструкций.
  4. Еще одна возможная классификация:
    • Класс

      Причина

      Синхронное/Асинхронное

      Поведение при возврате

      Аварийное завершение(abort)

      Фатальная ошибка

      Да

      Нет возврашения

      Сбой(fault)

      Потенциально восстановимая ошибка

      Да

      Возможен возврат к следующей инструкции

      Системное прерывание(trap)

      Предусмотренное исключение

      Да

      Возврат к следующей инструкции

      Аппаратное прерывание(interrupt)

      Сигнал устройства ввода/вывода

      Нет

      Возврат к следующей инструкции

  5. Обработка исключений в MIPS на примере эмулятора Mars.
    1. MARS имитирует основные элементы механизма MIPS32 исключений. Набор инструкций MIPS включает в себя ряд инструкций, которые вызывают исключение ловушки на основе относительных значений двух регистров или непосредственного значения и регистра:
      • ten, teqi (ловушки если равно), tne, tnei (ловушки, если не равны), tge, tgeu, tgei, tgeiu (ловушкой, если больше или равно), tlt, tltu, tlti, tltiu (ловушка, если меньше).
      • MARS содержит сопроцессор управления(сопроцессор 0). Инструкции mfc0 и mtc0 используются для чтения и записи данных в сопроцессор 0.
    2. Когда происходит исключение процессор совершает следующие действия:
      • Устанавливает бит 1 регистра $12 (статус).
      • Устанавливает биты 2-6 регистра $13(причина) согласно типу исключения (коды ниже).
      • Устанавливает регистр $14 (EPC). В регистре сохраняется адрес инструкции, вызвавшей исключение.
      • Если исключение было вызвано обращением к неправильному адресу памяти, регистр $8 (vaddr) устанавливается на этот неверный адрес.
      • Поток выполнения переключается с текущей инструкции MIPS на адрес 0x800000180. Этот адрес в сегменте текста ядра (.kext) является стандартным для расположение обработчика исключений MIPS32.

      • Если нет инструкции по месту 0x800000180, Mars завершит работу программы MIPS с соответствующим сообщением об ошибке.
      • Обработчик исключений может вернуть управление программе, используя команду eret. Это поместит значение из "EPC" (регистр $14) в счетчик команд("PC"). Увеличение регистра $14 на 4 перед возвращением позволит пропустить инструкцию, вызвавшую исключение.
    3. Типы исключений (не обязательно реализованы):
      • ADDRESS_EXCEPTION_LOAD (4)
      • ADDRESS_EXCEPTION_STORE (5)
      • SYSCALL_EXCEPTION (8),
      • BREAKPOINT_EXCEPTION (9),
      • RESERVED_INSTRUCTION_EXCEPTION (10),
      • ARITHMETIC_OVERFLOW_EXCEPTION (12),
      • TRAP_EXCEPTION ( 13),
      • DIVIDE_BY_ZERO_EXCEPTION (15),
      • FLOATING_POINT_OVERFLOW (16),
      • FLOATING_POINT_UNDERFLOW (17).
      • NB Int(0) неявно.(хак MARS)

    4. Регистры $k0 и $k1 по соглашениям могут быть использованы свободно.
    5. Простой пример:
      •    1    .text
           2 main:
           3    teqi $t0,0     # immediately trap because $t0 contains 0
           4    li   $v0, 10   # After return from exception handler, specify exit service
           5    syscall        # terminate normally
           6 
           7 # Trap handler in the standard MIPS32 kernel text segment
           8 
           9    .ktext 0x80000180
          10    move $k0,$v0   # Save $v0 value
          11    move $k1,$a0   # Save $a0 value
          12    la   $a0, msg  # address of string to print
          13    li   $v0, 4    # Print String service
          14    syscall
          15    move $v0,$k0   # Restore $v0
          16    move $a0,$k1   # Restore $a0
          17    mfc0 $k0,$14   # Coprocessor 0 register $14 has address of trapping instruction
          18    addi $k0,$k0,4 # Add 4 to point to next instruction
          19    mtc0 $k0,$14   # Store new address back into $14
          20    eret           # Error return; set PC to value in $14
          21    .kdata
          22 msg:
          23    .asciiz "Trap generated"
        
  6. Приложение
    1. Coprocessor_0 Mars

      Название

      Номер

      Назначение

      BadVAddr

      8

      Адрес при обращении к которому произошло исключение

      Status

      12

      Состояние: маска прерываний, биты разрешений, ...

      Cause

      13

      Тип исключения и биты отложенных прерываний

      EPC

      14

      Адрес инструкции, которая вызвала исключение

    2. Инструкции для работы с регистрами Cop_0:
      • mfc0 Rdest, C0src
      • mtc0 Rsrc, C0dest
      • eret
    3. Регистр Status:

      bits

      31-16

      15-8

      7-5

      4

      3,2

      1

      0

      target

      unused

      Int. mask

      unuse

      K/U

      unused

      Exception level

      Int enable

    4. Interrupt mask - Mаска прерываний. Бит равен 1, если соответствующее прерываний разрешено.
    5. K/U - не стимулируется Mars; всегда 1.
    6. Exception level - устанавливается автоматически при исключении; предотвращает повторный вход.
    7. Interrupt enable - глобальное разрешение прерываний (0 - отключить).
    8. Регистр Cause:

      bits

      31

      30-16

      15-8

      7

      6-2

      1-0

      target

      Br

      unused

      Pending interrupts

      unused

      Exception code

      unused

    9. Br - 1 если исключение произошло на инструкции в слоте задержки перехода.
    10. Pending interrupts - ожидающие прерывания.
    11. Exception code - код исключения.

Внешние устройства и ввод/вывод

Устройства компьютера возожно разделить на два вида:

  • внутренние (процессор, ОЗУ);
  • внешние (периферийные).

Вычислительная система состоящая только из процессора и памяти мало полезна. Для повышения практической полезности ЭВМ снабжается периферийными устройствами(ПУ).

Внешние(периферийные) устройства ЭВМ, - устройства, предназначенные для внешней машинной обработки информации (в отличие от преобразований информации, осуществляемых центральным процессором). По роду выполняемых операций П. у. подразделяются на след. группы: устройства подготовки данных, служащие для занесения информации на промежуточные носители данных (перфорационные карты, перфорационные ленты, магнитные ленты, магнитные диски и др.); устройства ввода - для считывания информации и её преобразования в кодовую последовательность электрических сигналов, подлежащих передаче в центральный процессор; устройства вывода - для регистрации результатов обработки информации или их отображения (дисплей, принтер, графопостроитель и др.); устройства хранения больших объёмов информации (запоминающие устройства на магнитных дисках ...); устройства передачи информации на большие расстояния, обеспечивающие взаимодействие многих пользователей с ЭВМ (аппаратура передачи данных и др.).

  1. ПУ имеют регистры. На программном уровне всё управление ПУ сводится к чтению/записи регистров устройства.

    CPU

    r/w

    ПУ

    <->

    Data registers

    -->

    Control registers

    <--

    Status registers

    При работе с ПУ процессор выполняет функции, к числу которых относится:

    • арбитраж (выбор устройств по приоритету);
    • поиск периферийного устройства по заданному адресу;
    • передача периферийному устройству команды на исполнение;
    • анализ состояния ПУ (получение от ПУ информации об его состоянии);

    • поискПУ, запрашивающего обслуживание;

    • прием и передача данных от ПУ;

    • управление памятью.
  2. Порт(многозначность и связанная с этим путаница). IN, OUT.

  3. Отображение регистров на память("MMIO").
  4. Программный опрос ПУ, как способ организации взаимодействия.

  5. Пример терминала в Mars:

    Tools -> Keyboard adn Display MMIO Simulator

       1 # Memory mapped address of device registers.
       2 # 0xFFFF0000 rcv contrl
       3 # 0xFFFF0004 rcv data
       4 # 0xFFFF0008 tx contrl
       5 # 0xFFFF000c tx data
       6 
       7         .text
       8 main:
       9 loop:
      10         jal     getc
      11         beq $v0,0x32, exit
      12         ori     $a0, $v0, 0
      13         jal     putc
      14 
      15         nop
      16         nop
      17         nop
      18         nop
      19         nop
      20         j loop
      21 exit:
      22         li      $v0, 10
      23         syscall
      24 
      25 getc:
      26 #       v0 = received byte
      27         lui     $t0,0xffff
      28 gcloop:
      29         lw      $t1,0($t0)              # read rcv ctrl
      30         andi    $t1,$t1,0x0001          # extract ready bit
      31         beq     $t1,$0,gcloop           # keep polling till ready
      32         lw      $v0,4($t0)              # read data and rtn
      33         jr      $ra
      34 
      35 putc:
      36 #       a0 = byte to trransmit
      37         lui     $t0,0xffff
      38 pcloop:
      39         lw      $t1,8($t0)              # read tx ctrl
      40         andi    $t1,$t1,0x0001          # extract ready bit
      41         beq     $t1,$0,pcloop           # wait till ready
      42         sw      $a0, 0xc($t0)           # write data
      43         jr      $ra
      44 
      45         .data
    
  6. Примечания:
    • Keyboard adn Display MMIO Simulator использует для управления и передачи данных четыре регистра:
    • 0xFFFF0000 rcv contrl
      • bits

        31-2

        1

        0

        target

        unused

        Int

        ready

    • 0xFFFF0004 rcv data
      • bits

        31-8

        7-0

        target

        unused

        Resived Byte

    • 0xFFFF0008 tx contrl
      • bits

        31-2

        1

        0

        target

        unused

        Int

        ready

    • 0xFFFF000c tx data
      • bits

        31-8

        7-0

        target

        unused

        Transmitted Byte

Прерывания и DMA

  1. Прерывание — сигнал, сообщающий процессору о наступлении какого-либо внешнего события.
    • асинхронны
    • позволяют освободить cpu от активного ожидания.
  2. Проблемы возникающие при обработке прерываний:
    • распознавание природы прерывания
    • прерывания важны
    • прерывания нужно быстро обработать
  3. Маскирование прерываний.
    • Прерывания, в зависимости от возможности запрета, делятся на:
      • маскируемые — прерывания, которые можно запрещать установкой соответствующих битов в регистре маскирования прерываний;
      • немаскируемые — обрабатываются всегда, независимо от запретов на другие прерывания.
  4. Приоритеты обслуживания прерываний.
  5. Прерывания в Mars.
    1. Микропроцессор имеет входы прерывания.
    2. Каждый запрос прерывания может индивидуально маскироваться(включаются при 1) соответствующими разрядами поля Int Mask в регистре Status. Все запросы прерываний маскируются при установке значения бита IЕ=1 в регистра Status.
    3. Все прерывания обнаруживаются процессором. При поступлении сигналов прерывания процессор сбрасывает(0) биты поля ExcCode регистра Cause. При этом содержимое поля IP регистра Cause будет показывать, на какие входы поступили сигналы прерывания. При поступлении нескольких запросов прерывания приоритет их обслуживания должен задаваться программой-обработчиком.

    4. Сигнал прерывания продолжает восприниматься процессором после начала обработки прерывания. Чтобы избежать повторного обслуживания запроса, программа-обработчик должна выдать сообщение соответствующему внешнему устройству на снятие запроса прерывания или произвести маскирование запроса путем сброса в 0 соответствующего бита IMx регистре Status.
  6. Пример:
       1 .text
       2         .globl main
       3 main:
       4         mfc0 $a0, $12                   # read from the status register
       5         ori $a0, 0xff11                 # enable all interrupts
       6         mtc0 $a0, $12                   # write back to the status register
       7 
       8         lui $t0, 0xFFFF                 # $t0 = 0xFFFF0000;
       9         ori $a0, $0, 2                          # enable keyboard interrupt
      10         sw $a0, 0($t0)                  # write back to 0xFFFF0000;
      11                 
      12 here: 
      13         j here                          # stay here forever
      14         nop
      15         li $v0, 10                              # exit,if it ever comes here
      16         syscall
      17 
      18 
      19 .ktext 0x80000180                               # kernel code starts here
      20         
      21         .set noat                               # tell the assembler not to use $at, not needed here actually, just to illustrae the use of the .set noat
      22         move $k1, $at                   # save $at. User prorams are not supposed to touch $k0 and $k1 
      23         .set at                         # tell the assembler okay to use $at
      24         
      25         sw $v0, s1                              # We need to use these registers
      26         sw $a0, s2                              # not using the stack because the interrupt might be triggered by a memory reference 
      27                                         # using a bad value of the stack pointer
      28 
      29         mfc0 $k0, $13                   # Cause register
      30         srl $a0, $k0, 2                         # Extract ExcCode Field
      31         andi $a0, $a0, 0x1f
      32 
      33     bne $a0, $zero, kdone                       # Exception Code 0 is I/O. Only processing I/O here
      34     nop
      35     
      36         lui $v0, 0xFFFF                 # $t0 = 0xFFFF0000;
      37         lw $a0, 4($v0)                  # get the input key
      38         li $v0,1                                # print it here. 
      39                                         # Note: interrupt routine should return very fast, so doing something like 
      40                                         # print is NOT a good practice, actually!
      41         syscall
      42 
      43         li $v0,4                                # print the new line
      44         la $a0, new_line
      45         syscall
      46 
      47 kdone:
      48         mtc0 $0, $13                            # Clear Cause register
      49         mfc0 $k0, $12                   # Set Status register
      50         andi $k0, 0xfffd                        # clear EXL bit
      51         ori  $k0, 0x01                          # Interrupts enabled
      52         mtc0 $k0, $12                   # write back to status
      53     
      54     lw $v0, s1                          # Restore other registers
      55         lw $a0, s2
      56 
      57         .set noat                               # tell the assembler not to use $at
      58         move $at, $k1                   # Restore $at
      59         .set at                                 # tell the assembler okay to use $at
      60 
      61         eret                                    # return to EPC
      62     nop
      63 
      64 .kdata                                  # kernel data
      65 s1:     .word 10
      66 s2:     .word 11
      67 new_line: 
      68         .asciiz "\n"
    
  7. DMA - прямой доступ к памяти.

Кэш-память

  1. Зачем.Локальность.За всё время существования вычислительной техники устойчиво наблюдаются два явления:
    • Основная память работает значительно медленнее процессора.
    • Обращения к памяти происходят локально в пространстве и времени.
    Эти замечательные факты позволяют увеличить скорость выполнения вычислений, создав кэш. Кэш — промежуточный буфер с быстрым доступом, содержащий информацию, которая может быть запрошена с наибольшей вероятностью.
  2. Организация буферизации:
    • Вся оперативная память может быть разбита на блоки.
    • Кэш состоит из строк вида: бит достоверности, тэг, блок, возможная дополнительная информация.
    • Обмен между ОЗу и кэше происходит блоками.
    • Среднее время доступа = время доступа к нужному полю кэш-строки + ( 1 - коэффициент совпадения) время доступа к основной памяти.
  3. Виды:
    • прямого отображения
    • полностью ассоциативный
    • n-канальный множественно-ассоциативный кэш
  4. Промахи
  5. стратегии записи:
    • Сквозная.
    • Обратная.
    • С процессом записи связана еще одна проблема: а что происходит, если нужно записать что-либо в ячейку, которая в текущий момент не находится в кэш-памяти? Должны ли данные переноситься в кэш-память или просто записываться в основную память? Ни один из вариантов не является во всех отношениях лучшим. В большинстве разработок, в которых применяется обратная запись, данные переносятся в кэш-память. Эта технология называется заполнением по записи (write allocation). С другой стороны, в тех разработках, где применяется сквозная запись, обычно элемент в кэш-память при записи не помещается, поскольку эта возможность усложняет разработку. Заполнение по аписи полезно только в том случае, если имеют место повторные записи в одно и то же слово или в разные слова в пределах одной строки кэш-памяти.
  6. Разделение кэш-памяти на память данных и память инструкций.
    • Разделенная кэш-память позволяет осуществлять параллельный доступ, а общая — нет. К тому же, поскольку команды обычно не меняются во время выполнения, содержание командной кэш-памяти никогда не приходится записывать обратно в основную память, что упрощает реализацию.
  7. Уровни кэш-памяти.
  8. пример из Marsa
  9. пример на предсказании не перехода.
  10. Управление кэшированием. Текущие абстракции.

Что такое кэш процессора, и как он работает

Кэш про­цес­со­ра

Эффективность выполнения инструкций

  1. Цикл работы процессора:
    • Загрузка инструкции (IF = Instruction Fetch)

      Декодирование инструкции, выделение команды и операндов, чтение регистров (ID = Instruction Decode)

      Фактическое выполнение инструкции (Ex = Execute)

      Сохранение регистра в память, Загрузка регистра из памяти (MEM = Memory access)

      Запись результата регистр (WB = Writeback)

  2. Мысленный эксперимент.
    • Предположим существует возможность создать для каждой стадии цикла исполнения инструкции полностью автономное устройство(микросхему или часть микосхемы). Предположим также, что эти устройства могут быть последовательно связаны. Тогда для вычисления одной инструкции понадобится целых пять циклов.

    НО:

    1. Мы можем повысить тактовую частоту, поскольку максимальная задержка теперь стала меньше.
    2. Во время каждого цикла мы можем использовать все части тракта данных.
  3. Принципиальная схема MARS. => параллельная загрузка узлов

  4. Конвейер
    • В RISC-ядре процессора реализован конвейер, состоящий из пяти стадий и аналогичный конвейеру ядра R3000. Конвейер дает возможность процессору работать на высокой частоте, при этом минимизируется сложность устройства, а также уменьшается стоимость и потребление энергии.
    1. Стадии конвейера
      • Конвейер содержит пять стадий: На Рисунке 1 показаны операции, выполняемые CPU-ядром на каждом этапе конвейера.

        ris_1.png

      • Стадия I: выборка команды
        • На этой стадии команда выбирается из командного кэша.
      • Стадия D: дешифрация команды
        • На этой стадии:
          1. Операнды выбираются из регистрового файла.
          2. Операнды передаются на эту стадию со стадий E, M и W.
          3. ALU определяет, выполняется ли условие перехода и вычисляет виртуальный адрес перехода для команд перехода.
          4. Осуществляется преобразование виртуального адреса в физический.
          5. Производится поиск адреса команды по TLB и вырабатывается признак hit/miss.
          6. Командная логика выбирает адрес команды.
      • Стадия E: исполнение
        • На этой стадии:
          1. ALU выполняет арифметические или логические операции для команд типа регистр-регистр.
          2. Производится преобразование виртуального адреса в физический для данных, используемых командами загрузки и сохранения.
          3. Производится поиск данных по TLB и вырабатывается признак hit/miss.
          4. Все операции умножения и деления выполняются на этой стадии.
      • Стадия M: выборка из памяти
        • На этой стадии осуществляется загрузка и выравнивание загруженных данных в границах слова.
      • Стадия W: обратная запись
        • На этой стадии для команд типа регистр-регистр или для команд загрузки результат записывается обратно в регистровый файл.
    2. Операции умножения и деления
      • Время выполнения этих операций соответствует 17 тактам для команд умножения и 18 тактам для команд умножения с накоплением, а также 33 тактам для команд деления и 34 тактам для команд деления с накоплением.
    3. Задержка выполнения команд перехода (Jump, Branch)
      • Конвейер осуществляет выполнение команд перехода с задержкой в один такт. Однотактная задержка является результатом функционирования логики, ответственной за принятие решения о переходе на стадии D конвейера. Эта задержка позволяет использовать адрес перехода, вычисленный на предыдущей стадии, для доступа к команде на следующей D-стадии. Слот задержки перехода (branch delay slot) позволяет отказаться от остановок конвейера при переходе. Вычисление адреса и проверка условия перехода выполняются одновременно на стадии D. Итоговое значение PC (счетчика команд) используется для выборки очередной команды на стадии I, которая является второй командой после перехода. На Рисунок 2 показан слот задержки перехода.

        ris_2.png

    4. Обходные пути передачи данных (Data bypass)
      • Для большинства команд MIPS32 исходными операндами являются значения, хранящиеся в регистрах общего назначения. Эти операнды выбираются из регистрового файла в первой половине D-стадии. После исполнения на ALU результат, в принципе, готов для использования другими командами. Но запись результата в регистровый файл существляется только на стадии W. Это лишает следующую команду возможности использовать результат в течение 3-х циклов, если ее операндом является результат выполнения последней операции, сохраненный в регистровом файле. Для преодоления этой проблемы используются обходные пути передачи данных. Мультиплексоры обходных путей передачи данных для обоих операндов располагаются между регистровым файлом и ALU (Рисунок 3). Они позволяют передавать данные с выхода стадий E, M и W конвейера прямо на стадию D, если один из регистров источника (source) декодируемой команды совпадает с регистром назначения (target) одной из предшествующих команд. Входы мультиплексоров подключены к обходным путям M->D и E->D, а также W->D.

        ris_3.png

        На Рисунке 4 показаны обходные пути передачи данных для команды Add 1 , за которой следует команда Sub 2 и затем снова Add 3 . Поскольку команда Sub 2 в качестве одного из операндов использует результат операции Add 1 , используется обходной путь E->D. Следующая команда Add 3 использует результаты обеих предшествующих операций: Add 1 и Sub 2 . Так как данные команды Add 1 в это время находятся на стадии M, используется обходной путь M->D. Кроме того, вновь используется обходной путь E->D для передачи результата операции Sub 2 команде Add 3 . ris_4.png

    5. Задержка загрузки данных
      • Данные, выбираемые командами загрузки (Load), становятся доступными на конвейере только после выравнивания на стадии M. При этом данные, являющиеся исходными операндами, должны предоставляться командам для обработки уже на стадии D. Поэтому, если сразу за командой загрузки следует команда, для которой один из регистров исходных операндов совпадает с регистром, в который производится загрузка данных, это вызывает приостановку в работе конвейера на стадии D. Эта приостановка осуществляется аппаратной вставкой команды NOP. Во время этой задержки часть конвейера, которая находится дальше стадии D, продолжает продвигаться. Если же команда, использующая загружаемые данные, следует за командой загрузки не сразу, а через одну или через две, то для обеспечения бесперебойной работы конвейера используется один из обходных путей передачи данных: M->D или W->D (Рисунок 5). ris_5.png

  5. Пример конвейера на MIPS
    • Конфликт по данным
    • Конфликт по управлению
      • Варианты:
    • не обнаруживать (пускай компилятор думает)
    • обнаруживать (процессор)
      • переупорядочивать микрокоманды
      • возможно, сразу нескольких инструкций, если они развязаны (суперскалярность)
      • использовать несколько вычисляющих устройств для развязанных по данным команд (векторность)
      • опережающее выполнение, предсказание по переходам и т. д.
  6. Дополнение.
    • Архитектура MIPS предусматривает два типа блокировок:
      • Stall – конвейер останавливается полностью и ожидает снятия блокировки;
      • Slip – останавливается только часть конвейера – ступень, которая вызвала блокировку, и все более ранние ступени. Более поздние ступени завершаются. Например, при блоки ровке стадии E более поздние стадии M и W могут быть завершены. При этом до снятия блокировки на стадии E конвейер вставляет пустые команды NOP на стадии A и W, которые также называются bubble.
      Ещё одной особенностью работы конвейера является задержка при выполнении инструкций перехода JUMP или BRANCH. Рассмотрим ассемблер ный код:
      •    1    AND $s1, $v1, $t2
           2    j 0xFE00
           3    ORI $t2, $t3, 0x10
        
      После инструкции AND выполняется безусловный переход по адресу, заданному командой J. Задержка заключается в том, что инструкция, следующая непосредственно за командой перехода (в данном случае ORI), всегда выполняется. Это связано с тем, что решение о переходе и вычисление нового адреса программного счётчика принимается на стадии D, т.е. в момент времени, когда следующая инструкция уже поступила на стадию I. Во избежание пустого цикла эта инструкция также выполняется. При генерации машинного кода задержка учитывается автоматически. Инструкция J будет размещена в бинарном файле до инструкции AND. Если такую замену произвести невозможно, ассемблер вставляет дополнительную инструкцию NOP после команды перехода.

      UPD Предполагается, что условный переход не происходит, что важно для циклов.

Аппаратная поддержка многозадачности

Понятие контекста и переключения контекстов

  • Кто7 Супервизор
  • Как? По таймеру

Разделение памяти

  • PIC
  • Изолированное отображение памяти
    • с использованием регистра смещения
    • с использованием страниц и VMM

Всякое

  • swapping
  • paging
  • overcommit и page fault

Многопроцессорные системы

Многопроцессорность (мультипроцессорность, многопроцессорная обработка, англ. multiprocessing) — использование в составе одного устройства двух или более физических процессоров.

Таксономия Флинна:

  • ОКОД — Вычислительная система с одиночным потоком команд и одиночным потоком данных (SISD, Single Instruction stream over a Single Data stream).
  • ОКМД — Вычислительная система с одиночным потоком команд и множественным потоком данных (SIMD, Single Instruction, Multiple Data).
  • МКОД — Вычислительная система со множественным потоком команд и одиночным потоком данных (MISD, Multiple Instruction Single Data).
  • МКМД — Вычислительная система со множественным потоком команд и множественным потоком данных (MIMD, Multiple Instruction Multiple Data).

Потенциальные возможности (общая память и реальный параллелизм SMP)

  • Проблема: атомарный доступ к памяти
    • аппаратный семафор
      •    1 try: add $t0,$zero,$s4  #copy exchange value
           2      ll  $t1,0($s1)     #load linked
           3      sc  $t0,0($s1)     #store conditional
           4      beq $t0,$zero,try  #branch store fails
           5      add $s4,$zero,$t1  #put load value in $s4
        
    • Big Kernel Lock

  • Проблема: обработка прерываний
    • контроллер прерываний (решает, на какой процессор послать) и глобальные прерывания
    • локальные прерывания
    • APIC

  • Проблема: когерентность кэша

  • Проблема: памяти
  • Проблема: межпроцессорного обмена
    • коммутация, топология
    • кластерные системы

    • Закон Амдала: В случае, когда задача разделяется на несколько частей, суммарное время её выполнения на параллельной системе не может быть меньше времени выполнения самого длинного фрагмента

Non-SMP, кластеры

Виртуализация

Новые условия эксплуатации:

  • Унификация HW
  • Оперативное (горячее) изменение аппраратного профиля (память, диск, количество CPU)
  • доступность и миграция

=>

  • Виртуализация HW
  • Проброс HW
  • Гипервизор
  • Двойная (многомерная) косвенность VMM
  • Дедупликация и т. д.

Обзор архитектур современных ЭВМ

ARM

  1. Инструкции ARM(Паттерсон)
    • ARM является наиболее популярной архитектурой набора инструкций для встроенных устройств и используется на более чем трех миллиардах производимых за каждый год устройств. Изначально предназначенная для системы Acorn RISC Machine, название которой позднее изменилось на Advanced RISC Machine, apхитектура ARM появилась в том же году, что и архитектура MIPS, и следовала схожим принципам. Все совпадения перечислены в табл. 2.11. Принципиальное отличие заключалось в том, что у MIPS больше регистров, а у ARM — больше режимов адресации. Табл. 2.11 Сходство наборов инструкций ARM и MIPS

      ARM

      MIPS

      год представления

      1985

      1985

      размер инструкции

      32

      32

      размер адресного пространства

      32, плоское

      32, плоское

      выравнивание данных

      да

      да

      модели адресации данных

      9

      3

      целочисленные регистроы

      16 GPO регистров, по 32 бита

      31 GPO регистров, по 32 бита

      ввод-вывод

      с отображением на память

      с отображением на память

      Как показано в табл. 2.12. для MIPS и для ARM использовались похожие основные наборы арифметическо-логических инструкций и инструкций переноса данных.

      tabl_2_12_1.png tabl_2_12_2.png Таблица 2.12. ARM-инструкции типа регистр-регистр и инструкции переноса данных, эквивалентные основным инструкциям MIPS. прочерки означают, что операция в этой архитектуре недоступна или не синтезирована в виде нескольких инструкций. Если имеется сразу несколько инструкций, эквивалентных основным инструкциям MIPS, они разделены запятыми. Сдвиги в ARM включены в виде части каждой инструкции обработки данных, поэтому сдвиги c верхним индексом 1 являются всего лишь разновидностью инструкции move. например lsг‘. Заметьте. что в ARM нет инструкции деления

  2. Режимы адресации.
    • B табл. 2.13 показаны режимы адресации данных, поддерживаемые в ARM. B отличие от MIPS ARM не выделяет регистр для содержания нулевого начения. В MIPS имеется всего три простых режима адресации данных (см. рис. 2.12), a вот у ARM имеется девять режимов, которые включают довольно сложные вычисления. Haпример, в ARM имеется режим адресации, который для формирования адреса может сдвигать значение одного регистра на любое количество позиций, добавлять его к значениям других регистров, а затем обновлять значение одного из регистров, присваивая ему значение полученного нового адреса. табл. 2.13

      Режим адресации

      ARM v.4

      MIPS

      регистровый

      +

      +

      непосредственный

      +

      +

      регистр + смещение( побазе)

      +

      +

      регистр + регистр(индексированный)

      +

      -

      регистр + маштабированныйрегистр(маштабированный)

      +

      -

      регистр + смещение и обновление регистра

      +

      -

      регистр + регистр и обновление регистра

      +

      -

      автоинкрементный,автодэкрементный

      +

      -

      относительный по PC

      +

      -

      Таблица 2.13. Сводка режимов адресации данных. В ARM имеются отдельные режимы косвенной регистровой адресации и адресации «регистр + смещение», простое помещения нуля в смещение во втором режиме не используется, чтобы получить более широкий диапазон адресации, ARM сдвигает смещение на один или два разряда влево, если размер данных составляет полуслове или слово
  3. Сравнение и условный переход
    • B MIPS для вычисления условий переходов используется содержимое регистров. В ARM используются традиционные четыре разряда кода условия, сохраняемые в слове состояния программы: отрицательный, нулевой, переноса и переполнения - negative, zero. carry и overflow. Они могут устанавливаться при выполнении любой арифметической или логической инструкции; в отличие от более ранних архитектур эта установка для каждой инструкции является выборочной. Явный выбор создает меньше проблем при конвейерной реализации. В ARM используются условные переходы для проверки кодов условий, чтобы определить все знаковые и беззнаковые соответствия. Инструкция сравнения - CMP вычитает один операнд из другою. а пo разнице устанавливает коды условия. Инструкция отрицательного сравнения — compare-negative (CMN) — прибавляет один операнд к другому, а по сумме устанавливает коды условий. Инструкция ТSТ выполняет логическое И двух операндов для установки всех кодов условий, кроме переполнения - overflow, а инструкция TEQ использует исключающее ИЛИ для установки значений первых трех кодов условий. Одно из необычных свойств ARM заключается в том. что каждая инструкция имеет настройку на условное выполнение в зависимости от кодов условий. Каждая инструкция начинается с четырехразрядного поля. определяющего, будет ли она работать как холостая инструкция — no operation instruction (nop) — или как настоящая инструкция, в зависимости от кодов условий. Следовательно, по сути условные переходы рассматриваются как условное выполнение инструкции безусловного перехода. Условное вы волнение позволяет избежать перехода путем обхода его инструкции. На простое условное выполнение одной инструкции требуется меньше времени и пространства для кода. На рис. 2.16 показаны форматы инструкций для ARM и MIPS. Принципиальная разница заключается в четырехразрядном поле условного выполнения в каждой инструкции и меньшем по размеру поле регистра, потому что во ARM используется в два раза меньше регистров.
    • ris_2_16.png Рис. 2.16. Форматы инструкций ARM и MIPS. Разница заключается в том, что в одной архитектуре 16. а в другой 32 регистра

  4. Уникальные характеристики ARM
    • B табл. 2.14 показаны несколько арифметическо-логических инструкций. отсутствующих в MIPS. За неимением специально выделенного регистра, содержащего нуль. в этой архитектуре есть отдельные коды для выполнения тех операций, которые в MIPS реализуются с помощью регистра $zero. Кроме того, в ARM имеется поддержка для арифметики, оперирующей несколькими словами. Поле непосредственного значения ARM. состоящее из 12 разрядов, имеет новую интерпретацию. Восемь самых младших разрядов расширяются нулями до 32-разрядного значения, затем прокручиваются вправо на количество разрядов, указанное в первых четырех разрядах поля и умноженное на два. Одно из преимуществ заключается в том, что такая схема может представить все степени двойки в 32-разрядном слове. Было бы интересно исследовать вопрос, позволяет ли такое разделение охватить больше непосредственных значений, чем простое 12-разрядное поле. Операнд, подвергающийся сдвигу, не ограничивается непосредственными значениями. У второю регистра всех арифметических и логических операций по обработке данных есть возможность подвергнуться сдвигу еще до того, как он будет использован в операции. вариантами сдвига являются логический сдвиг влево, логический сдвиг вправо, арифметический сдвиг вправо и вращение вправо.

      Таблица: 2.14. Арифметические и логические инструкции ARM. отсутствующее в MIPStabl_2_14.png

    • В ARM также имеются инструкции для сохранения групп регистров. называемые блочными загрузками и сохранениями. Под управлением 16-разрядной маски внутри инструкций любой из 16 регистров может быть загружен из памяти или сохранен в ней с помощью одной инструкции. Эти инструкции могут сохранять и восстанавливать регистры при входе в процедуру и при возвращении из нее. Эти инструкции могут также использоваться для блочного копирования памяти, и сегодня блочное копирование приобретает все больший вес при их использование.
  5. Приложение ARM от Танненбаума ARM_Tan.pdf

Intel x86

  • Современные процессоры Intel x86 с расширениями Intel64 поддерживают множество режимов работы. Мы рассмотрим x86_64 (Руководства для разработчиков приложений для 64- и 32-разрядных архитектур Intel®) 256_64_and_IA-32_Architectures_Developer_s_Manual__Vol__1_-_64-i.png

    • Архитектура х86_64 является примером CISC-архитектуры (Complex Instruction Set Computer – компьютер с полным набором команд). В отличие от команд в RISC-архитектурах, таких как MIPS, каждая CISC-команда может определять больше работы. Из-за этого программы для CISC-архитектур обычно состоят из меньшего количества команд. Кодировки команд были подобраны так, чтобы обеспечивать наибольшую компактность кода – это требовалось в те времена, когда стоимость оперативной памяти было гораздо выше, чем сейчас. Команды имеют переменную длину (от 1 до 15 байт), большое количество часто используемых команд короче 32 бит. Недостаток же состоит в том, что сложные команды трудно дешифровать.
  1. Основные отличия между MIPS и x86_64
    • Характеристики

      MIPS

      x86_64

      Количество регистров

      32 общего назначения

      16 общего назначения, некоторые ограничения по использованию; 8 FPU/MMX, 16 XMM, 32 YMM

      Количество операндов

      3 (2 источника, 1 назначение)

      2 (1 источник, 1 источник/назначение), 3 (AVX)

      Расположение операндов

      Регистры или непосредственные операнды

      Регистры, непосредственные операнды или память

      Размер операнда

      32 бита

      8, 16, 32, 64, 128 или 256 бит (непосредственные операнды не более 64 бит)

      Коды условий

      Нет

      Да

      Типы команд

      Простые

      Простые и сложные

      Размер команд

      Фиксированный, 4 байта

      Переменный, 1–16 байтов

  2. Регистры:
    • 64-разрядные RAX, RBX, RCX, RDX, RSI, RDI, RSP, RBP и R8, R9, ..., R15;
    • 32-разрядные ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP, EBP; R8D—R15D являются младшими половинами 64-разрядных регистров;
    • 16-разрядные АХ, ВХ, CX, DX, SI, DI, SP, BP, R8W—R15W являются младшими частями 32-разрядных регистров;
    • 8-битные регистры АН, ВН, СН, DH и AL, BL, CL, DL, SIL, DIL, SPL, BPL, R8L—R15L — старшие и младшие части 16-битных регистров соответственно;
      • Эти шестнадцать регистров можно, за некоторым исключением, считать регистрами общего назначения. Некоторые команды не могут использовать некоторые из них. Другие команды всегда записывают результат в определенные регистры. Регистр RSP, как правило, используется как указатель стека. Счетчик команд в архитектуре х86 называется RIP (instruction pointer). Он увеличивается при переходе от одной команды к другой, а также может быть изменен командами ветвлений, безусловных переходов и вызова процедур.
    • Доступ к 64-битным регистрам и новым регистрам осуществляется через специальный REX-префикс. Таким образом, все опкоды команд, которые работают с 64-битными регистрами, увеличиваются в размере как минимум на 1 байт, и возникает серьёзная проблема оптимизации кода. Поэтому рекомендуется везде, где возможно, использовать 32-битные регистры.
  3. Расположение операндов
    • Команды х86_64 содержат только два операнда: операнд-источник и операнд-источник/назначение. Следовательно, команда х86 всегда записывает результат на место одного из операндов.

      Источник/Назначение

      Источник

      Пример

      Выполняемая функция

      Регистр

      Регистр

      add EAX, EBX

      EAX <– EAX + EBX

      Непосредственный операнд

      Регистр

      add EAX, 42

      EAX <– EAX + 42

      Регистр

      Память

      add EAX, [20]

      EAX <– EAX + Mem[20]

      Память

      Регистр

      add [20], EAX

      Mem[20] <- Mem[20] + EAX

      Непосредственный операнд

      Память

      add [20], 42

      Mem[20] <- Mem[20] + 42

      ! Возможны любые комбинации, исключая память–память.

    • В то время как MIPS всегда оперирует с 32-битными словами данных, команды х86 могут использовать 8-, 16- 32- или 64-битные данные. В 64-битном режиме размер адреса по умолчанию равен 8 байтам, размер операнда по умолчанию равен 4 байтам.
  4. Режимы адресации памяти
    • Архитектура х86_64 имеет 64-битное пространство памяти с побайтовой адресацией (существующие реализации поддерживают виртуальную адресацию до 48—52 бит, что связано с нежеланием вводить избыточные уровни Page Directory). х86_64 поддерживает много режимов адресации памяти. Расположение ячейки памяти задается при помощи комбинации регистра базового адреса, смещения и регистра масштабируемого индекса. Табл. Режимы адресации памяти

      Пример

      Назначение

      Комментарий

      add EAX, [20]

      EAX <– EAX + Mem[20]

      Смещение (displacement)

      add EAX, [ESP]

      EAX <– EAX + Mem[ESP]

      Базовая адресация

      add EAX, [EDX+40]

      EAX <– EAX + Mem[EDX+40]

      Базовая адресация + смещение

      add EAX, [60+EDI*4]

      EAX <– EAX + Mem[60+EDI*4]

      Смещение + масштабируемый индекс

      add EAX, [EDX+80+EDI*2]

      EAX <– EAX + смещение + Mem[EDX+80+EDI*2]

      Базовая адресация + масштабируемый индекс

    • Смещение может иметь 8-, 16- или 32-битное значение. Регистр масштабируемого индекса может быть умножен на 1, 2, 4 или 8. Режим базовой адресации со смещением аналогичен режиму относительной адресации в MIPS, используемому для команд загрузки и сохранения. Масштабируемый индекс обеспечивает простой способ доступа к массивам и структурам с 2-, 4- или 8-байтовыми элементами без необходимости использовать команды для явного расчета адресов.
    • В 64-битном режиме введён режим адресации относительно RIP. В случае адре­сации относительно RIP используются не 64-битные адреса данных и переходов, а 32-битные. Таким образом, можно достигнуть почти 40%-ного уменьшения размера кода.
  5. Флаги состояния
  6. Другие особенности х86:
    • Сегменты
    • Порты
    • Команды, работающие с цепочками (последовательностями или строками) байтов или слов. Эти команды реализуют операции копирования, сравнения и поиска определенного значения. В современных процессорах такие команды, как правило, работают медленнее, чем последовательность простых команд, делающих то же самое, поэтому их лучше избегать.
    • Префиксы — используются для изменения размера операндов, захвата внешней шины, предсказания ветвлений или повторения команды при обработке цепочки байтов или слов.
  7. PS
    • "У Intel 16—разрядный микропроцессор появился на два года раньше. чем более элегантные по архитектуре изделия его конкурентов, например микропроцессор Motlorola 68000, и это обстоятельство стало главным фактором выбора микропроцессора 8086 в качестве центрального процессора для компьютера IBM PC. Инженеры Intel в целом согласны с тем. что х86 труднее создавать, чем такие компьютерные системы, как ARM и MIPS. но более широкие рыночные возможности позволяют выделять больше ресурсов на преодоление дополнительных сложностей. Стилевые недостатки х86 компенсируются количественными показателями, создавая этому семейству привлекательность в обозримой перспективе." Patterson

ArchitectureAssembler2015/FullPages (последним исправлял пользователь FrBrGeorge 2024-06-17 12:55:48)