Несогласованность MIPS с прямым порядком байтов

Насколько я понимаю, существует несоответствие с порядком байтов в сборке MIPS при запуске на QtSpim (нет машины x86_64, что означает, что QtSpim является прямым порядком байтов). Однако я не уверен, ошибка это или я ошибаюсь.

Когда слово загружается в регистр, байты не меняются местами, чтобы отразить прямой порядок байтов. Например, если слово в памяти содержит 0x11223344 и мы загружаем его в регистр, мы получаем 0x11223344 (я ожидал бы 0x44332211).

Рассмотрим следующий фрагмент:

    .text
    .globl main
main:
    la   $t0, letters
    lw   $t1, 0($t0)   # Expected ($t1): 0x61626364
    sll  $t2, $t1, 8   # Expected ($t2): 0x62636400
    sw   $t2, 0($t0)   # Expected (mem): 0x00646362
    jr   $ra

    .data
letters:
    .ascii "abcd"

Перед запуском программы «abcd» сохраняется с прямым порядком байтов, как и ожидалось: 0x64636261 (dcba). После завершения программы я ожидаю, что 0x00646362 (\ 0dbc) будет сохранен в памяти, однако 0x63626100 (cba \ 0) будет сохранен.

Почему это так?

Проверено на Fedora 24, x86_64, QtSpim версии 9.1.17.


person plafer    schedule 18.11.2016    source источник


Ответы (1)


Нет никакой непоследовательности. Вы берете 0x64636261 и сдвигаете его на 8 бит влево (т.е. сдвигаете биты влево при сдвиге нулей справа). Итак, 0x64636261 становится 0x63626100.
Если вы хотели 0x00646362, вы должны были использовать srl вместо sll.

Вот диаграмма ASCII, показывающая взаимосвязь между 32-битным словом и отдельными байтами в конфигурации с прямым порядком байтов:

0x64636261
  | | | |
  | | | ----> |'a'| letters
  | | |       -----
  | | ------> |'b'| letters+1
  | |         -----
  | --------> |'c'| letters+2
  |           -----
  ----------> |'d'| letters+3
person Michael    schedule 18.11.2016
comment
Поскольку это метод прямого порядка байтов, я ожидаю, что мой регистр $t1 будет содержать 0x61626364 после загрузки (байты в обратном порядке) и 0x62636400 после сдвига влево. Когда мы сохраняем его обратно в память, он сохраняется в обратном порядке, что дает 0x00646362. Я делаю неправильные предположения? - person plafer; 18.11.2016
comment
Я делаю неправильные предположения?. да. В конфигурации с прямым порядком байтов младший байт находится по младшему адресу. Первый символ в letters - это 'a' (0x61), затем 'b' (0x62) и т. Д. Следовательно, lw из letters даст вам 0x64636261. - person Michael; 18.11.2016
comment
Строки @plafer хранятся в последовательном порядке, независимо от порядка байтов. - person phuclv; 18.11.2016
comment
@Michael lw из letters даст вам 0x64636261. Фактически, поскольку они хранятся 0x64636261, при загрузке я должен получить 0x61626364 (что подтверждается этим вопросом: stackoverflow.com/q/8050107 / 3499862 Если машина работает с прямым порядком байтов, выполняется обратное преобразование, а затем копируется в регистр.). Остальной мой вывод следует из этого факта. Я понимаю (как показано на схеме ASCII), как они размещаются в памяти, но мы не согласны с порядком, в котором они загружаются в регистр. Ясно ли теперь мое замешательство? - person plafer; 18.11.2016
comment
@ LưuVĩnhPhúc На самом деле, поскольку abcd хранится как 0x64636261 (dcba), я понимаю, что они хранятся как любой другой битовый шаблон. Little-endian vs Big-endian не зависит от типа битовой последовательности. - person plafer; 18.11.2016
comment
поскольку они хранятся 0x64636261, при загрузке я должен получить 0x61626364. Нет. Если у вас есть 0x64636261, хранящийся в памяти, значит, у вас есть 0x64636261, хранящийся в памяти, и это то, что вы должны получить обратно, когда загрузите его (как слово). На мой взгляд, вы смотрите на это с неправильной точки зрения. Строка - это массив символов, с первым символом в самом низком адресе, затем вторым символом и т. Д. Это независимо от порядка байтов. И если вы загружаете слово из памяти, младший байт будет происходить из младшего адреса (в конфигурации LE). Остальное следует из этого. - person Michael; 18.11.2016