2016-10-03 19 views
0

Я просто хочу проверить, что мое понимание этих двух понятий правильное, поскольку я пытался завершить проект, и, хотя все работает в моих ожиданиях, он почти не выполняет тестовые примеры и вводит случайное значение ...Разделитель адресов MIPS Адресация алгоритма и выделение кода из двоичного кода команды?

в принципе, цель проекта заключается в выписывать команду перехода на консоль в таком виде:

BranchName $ S, [$ т, если применимо] 0xAbsoluteAddressOfBranchTargetInstruction

Edit: Уточнение: Я пишу это в MIPS. Идея заключается в том, что я получаю адрес памяти в $ a0, заданный программе кодом моего инструктора (я пишу функцию). Адрес предназначен для слова, содержащего инструкцию MIPS. Я сделать следующее:

  1. Получить инструкции
  2. инструкция изолят опкод и вывод его имени для регистрации (т.е. опкод 5, выход BNE), ничего не делать, если это не команда ветвления.
  3. Изолировать $ s, $ t и выводить как применимо (т. Е.: Нет $ t для bgez)
  4. Использовать смещение в инструкции перехода для вычисления его абсолютного адреса (адреса целевой команды, следующего за ветвью) и вывода в шестигранный. Для целей этого расчета адрес команды перехода ($ a0) считается $ pc.

IE:

BEQ $ 6, $ 9, 0x00100008

Во-первых, это мое понимание расчета ветви правильно?

  1. PC -> PC + 4
  2. Младшие 16 битов инструкции
  3. < < 2 эти нижние биты
  4. Добавить PC + 4 и влево сдвинуты нижние 16 бит (только нижний 16, хотя) ,

Во-вторых, может кто-нибудь сказать мне, какие биты мне нужно изолировать, чтобы знать, с какой ветвью я имею дело? Я думаю, что у меня есть они (первые 6 для BEQ/BNE, первые 16 с $ s замаскированы для других), но я хотел дважды проверить.

О, и, наконец, я должен ожидать отклонения от SPIM от его работы в системе Intel x86 Windows и системе Intel x86 Linux? Я получаю глупый глюк, и я не могу его изолировать от моих обработок адресных обработок, но он появляется только при запуске тестовых скриптов, которые мой проф дал нам в Linux (.sh); работает прямо в spim на любой ОС, кажется, работает ... при условии, что мое понимание того, как выполнять ручные вычисления (как указано выше), является правильным.

+0

Я не думаю, что там будет разница между Windows и Linux, поскольку SPIM использует базовую «работоспособность» оборудования. – Zack

+1

Попробуйте использовать MARS вместо SPIM и посмотрите, получите ли вы тот же ответ. (http://courses.missouristate.edu/KenVollmar/mars/) – Zack

+0

@Zack Считаете ли вы, что это имеет какое-то отношение к моим чистым алгоритмическим соображениям? Я где-то читал, что Spim не беспокоит ПК + 4, что может привести к ошибке? –

ответ

1

Это предваряет мои различные комментарии.

Вот пример программы, которая правильно вычисляет адрес. Он делает не делает тип инструкции типа ветвления, поэтому вам придется объединить части этой и вашей версии вместе.

Обратите внимание, что для печати значений в гексагоне используется шкала вызовов mars. Это не доступно в соответствии с spim, так что вам может понадобиться для вывода в десятичной системе счисления, используя системный вызов 1 или написать свою собственную функцию вывода шестнадцатеричного значения [если вы еще не]

.data 
msg_best: .asciiz  "correct target address: " 
msg_tgt: .asciiz  "current target address: " 
msg_nl:  .asciiz  "\n" 

    .text 
    .globl main 
main: 
    la  $s0,inst    # pointer to branch instruction 
    la  $s1,einst    # get end of instructions 
    subu $s1,$s1,$s0    # get number of bytes 
    srl  $s1,$s1,2    # get number of instruction words 
    la  $s2,loop    # the correct target address 

    la  $a0,msg_best 
    move $a1,$s2 
    jal  printaddr 

loop: 
    move $a0,$s0 
    jal  showme     # decode and print instruction 
    addiu $s0,$s0,4 
    sub  $s1,$s1,1 
    bnez $s1,loop    # more to do? yes, loop 

    li  $v0,10 
    syscall 

    # branch instructions to decode 
inst: 
    bne  $s0,$s1,loop 
    beq  $s0,$s1,loop 
    beqz $s1,loop 
    bnez $s1,loop 
    bgtz $s1,loop 
    bgez $s1,loop 
    bltz $s1,loop 
    blez $s1,loop 
einst: 

# showme -- decode and print data about instruction 
# 
# NOTE: this does _not_ decode the instruction type 
# 
# arguments: 
# a0 -- instruction address 
# 
# registers: 
# t5 -- raw instruction word 
# t4 -- branch offset 
# t3 -- absolute address of branch target 
showme: 
    subu $sp,$sp,4 
    sw  $ra,0($sp) 

    lw  $t5,0($a0)    # get inst word 
    addiu $t3,$a0,4    # get PC + 4 

    sll  $t4,$t5,16    # shift offset left 
    sra  $t4,$t4,16    # shift offset right (sign extend) 
    sll  $t4,$t4,2    # get byte offset 

    addu $t3,$t3,$t4    # add in offset 

    # NOTE: as a diagnostic, we could compare t3 against s2 -- it should 
    # always match 

    la  $a0,msg_tgt 
    move $a1,$t3 
    jal  printaddr 

    lw  $ra,0($sp) 
    addu $sp,$sp,4 
    jr  $ra 

# printaddr -- print address 
# 
# arguments: 
# a0 -- message 
# a1 -- address value 
printaddr: 
    li  $v0,4 
    syscall 

    # NOTE: only mars supports this syscall 
    # to use spim, use a syscall number of 1, which outputs in decimal and 
    # then hand convert 
    # or write your own hex output function 
    move $a0,$a1 
    li  $v0,34     # output number in hex (mars _only_) 
    syscall 

    la  $a0,msg_nl 
    li  $v0,4 
    syscall 

    jr  $ra 
+0

Я передал модифицированный скрипт, чтобы получить целочисленные значения для тестовых случаев (addr, instr) и сравнить их. Как бы то ни было, вся моя проблема заключалась в том, что ключевое недоразумение о знаке, расширяющем биты, и добавлении слова WHOLE. Я не читал остальную часть вашего кода, так как это задание, но у вас есть моя благодарность за то, что помогли мне со сдвигом. Я не мог найти эту часть в своих заметках о слайде, поэтому я сделал это неправильно. СПАСИБО. –

1

16-битное мгновенное значение с расширением знака до 32 бит, а затем сдвинуто. Я не знаю, повлияет ли это на вашу программу; но, это единственная потенциальная «ошибка», которую я заметил.

+0

+1 для вероятной проблемы, но, также как и для предложения «mars» [написанного в java] выше. Spim имеет два варианта: 'spim', версия командной строки. И 'QtSpim' является версией gui. Они должны быть на 100% совместимы, но я иногда замечал проблемы. Это может быть значение по умолчанию, разрешено ли «интервалы задержки ветвления». –

+0

@ Zack Итак, с учетом сказанного ... как бы я подписывал продление его вручную до смены? Кроме того, я должен добавить все слово на компьютер? –

+0

@smitty_werbermanjensen, я не уверен, что полностью понимаю, что вы пытаетесь сделать. Вы пишете симулятор MIPS в C? Помогло ли высказывание Крейга выше? – Zack