Задача поворота влево в четной / нечетной сумме с использованием сборки отладчика Tracer SCO - PullRequest
0 голосов
/ 07 мая 2020

Я застрял в приведенном ниже коде. У меня есть следующий код для Tracer и SCO Debugger. Я компилирую его с помощью Dosbox, и я хочу добавить в код левый поворот, но не могу найти, куда я пытаюсь добавить ROL AX, 1, но он не работает.

Допустим, числа

четный 2,3,5,7,11

нечетный 1,3,5,7,9

Сумма 3,6,10,14,20

Я хочу, чтобы это выглядело как

3,5,7,11,2

, поэтому сумма будет

4,8,12,18,11

_EXIT = 1

.SECT .TEXT
start:
MOV BX, 0
MOV CX, 5

sum:
CMP BX, 5
JE done
NOP
MOVB AL,(BX)
ADD BX,odd
MOVB DL,(BX)
SUB BX,odd
ADDB AL,DL
ADD BX,result
MOV (BX),AX 
SUB BX,result
INC BX
LOOP sum

done:
MOV CX,5
MOV BX,result
print:
CMP BX,result + 5
JE exit
MOVB AL,(BX)
INC BX
LOOP print

exit:
PUSH _EXIT
SYS

.SECT .DATA
prime:
.BYTE 2,3,5,7,11
odd:
.BYTE 1,3,5,7,9
result:
.BYTE 0,0,0,0,0
.SECT .BSS

1 Ответ

0 голосов
/ 07 мая 2020

rol ax, 1 работает с битами в этом регистре, а не с байтами в массиве. То, что вы ищете, похоже на C ++ std::rotate(first, new_first, last) для поворота элементов массива.

Вы можете поменять местами два соседних байта в памяти с помощью rol word [mem], 8 или даже повернуть двойное слово на 8, 16 или 24 бит, чтобы переупорядочить байты в 4-байтовом фрагменте, но это все, что вы можете сделать с один поворот.

Так, например, вы можете сделать это:

        ;; starting with prime = .byte 2,3,5,7,11 
ror dword ptr [prime], 8             ; 3,5,7,2, 11   ; x86 is little-endian
ror word ptr  [prime+4], 8           ; 3,5,7, 11,2

Это ГАЗ .intel_syntax; Я не узнаю синтаксис, который вы используете. Он выглядит как гибрид AT&T и Intel с круглыми скобками для режимов адресации, но, похоже, это пункт назначения слева.

Это довольно неэффективно по сравнению с простой загрузкой всех 5 байтов и их сохранением в нужном месте их. В частности, вы получите остановку переадресации магазина, когда часть загрузки слова 2-го ror считывает 1 байт, который только что был сохранен частью хранилища dword первого ror. (Инструкция назначения памяти декодируется для загрузки + ALU + операций сохранения. Первое хранилище все еще будет в буфере хранилища, когда выполняется загрузка второго поворота. Предполагается, что современный процессор x86 выполняет этот код изначально; но поскольку вы находитесь в DOSBox, это фактически эмуляция не выполняется).

Более простой способ сделать это:

    mov    eax, [prime+1]         ; dword load: 3,5,7,11
    mov    dl,  [prime]           ; byte load: 2
    mov    [prime], eax
    mov    [prime+4], cl          ; 3,5,7,11,2

Это легко расширить для массивов большего размера. При необходимости вы можете написать al oop, чтобы скопировать элементы вперед, в то время как исходный первый элемент сохранен где-то еще (в регистре).

...