Копирование сборки из одного массива в другой - PullRequest
0 голосов
/ 19 мая 2018

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

int x, y;
for(int i=0;i<32;i++)
    for(int j=0;j<32;j++)
        area[x+i][y+j]=bomb[i][j];

Используя программу-ассемблер masm и notepad ++ для написания кода, я получил

mov ecx, 0 ; my i
outerloop:
    cmp ecx, 32
    je done
    mov esi, 0 ; my j
innerloop:
    mov ebx, sprite_width ; sprite_width=32
    mov eax, ecx
    mul ebx
    add eax, esi
    shl eax, 2
    mov edi, bomb
    add edi, eax
    mov pixel, edi  ; pixel = bomb[i][j]
    mov ebx, area_width
    mov eax, y
    add eax, ecx
    mul ebx
    add eax, x
    add eax, esi
    shl eax, 2
    mov edi, area
    add edi, eax
    mov eax, [pixel]
    mov dword ptr [edi], eax   ; should be area[x+i][y+j] = pixel
    cmp esi, 32
    je innerloopdone
    inc esi
    jmp innerloop
innerloopdone:
    inc ecx
    jmp outerloop
done:

После этого область 32x32 на экране должна выглядетькак бомба, из-за того, как написан вектор бомбы, однако я вижу только зеленый и синий.Синий даже не в векторе бомбы вообще.Есть ли ошибка в цикле / логике?

1 Ответ

0 голосов
/ 19 мая 2018

Поскольку вы не опубликовали определения этих символов, я просто догадываюсь, как они были определены, я ожидал бы что-то вроде:

area            dd  640*480 dup (0)         ; 640x480x32bpp "screen area"
area_width      dd  640
sprite_width    dd  32
sprite_height   dd  32
bomb            dd  32*32 dup (255)         ; 32x32 red pixels as "bomb" gfx placeholder

Тогда этого должно быть достаточно, чтобы нарисовать непрозрачную частьграфики более эффективным способом, чем ваше предложение:

    ; initialize registers before drawing lines
    ; make edi = address area[y][x]
    lea     edi,[area]
    mov     ebx,[area_width]
    mov     eax,[y]
    mul     ebx
    add     eax,[x]     ; eax = y*area_width + x
    shl     eax,2
    add     edi,eax     ; edi = area + (y*area_width + x)*4
    ; make ebx = (area_width - sprite_width)*4
    sub     ebx,[sprite_width]
    shl     ebx,2
    ; make esi = address bomb[0][0]
    lea     esi,[bomb]
    ; make edx = number of lines
    mov     edx,[sprite_height]   ; 32
line_loop:
    ; draw single line
    mov     ecx,[sprite_width]
    rep movsd
    ; move to the next line (esi already updated, edi must advance)
    add     edi,ebx
    ; loop until all lines are drawn
    dec     edx
    jnz     line_loop

Я не отлаживал его, поэтому может быть проблема, но у меня нет MASM, чтобы попробовать.


О вашем исходном коде есть повторяющаяся тема, в которой вы пишете что-то вроде:

    mov edi, bomb

vs

    mov eax, [pixel]

К сожалению, в MASM они идентичны, [] доступ к памятине требуется, когда вы используете symbol имя, то есть mov edi,bomb загружает значение из памяти, а не получает адрес бомбы.Чтобы получить адрес, используйте mov edi,OFFSET bomb в MASM или lea edi,[bomb].

Таким образом, вы смешиваете их, и иногда кажется, что вы действительно хотели получить адрес памяти, а иногда значение, а иногда вы сохраняете адрес впамять вместо значения и т.д ...

Также я настоятельно рекомендую вам начинать использовать [] вокруг символов, даже когда MASM не требует их, поэтому визуально легче обнаружить строки в коде, обращающемся к памятии стиль идентичен косвенной адресации через регистры (т. е. тот же стиль, что и mov eax,[ebx], где даже MASM нужны квадратные скобки).Посмотрите мой пример, как я последовательно использую [] при каждом доступе к памяти (кроме lea, когда процессор не обращается к памяти, только вычисляет адрес, но это связано с характером самой инструкции leaаргументом для него остается тип доступа к памяти).

Но самое главное найти какой-нибудь работающий отладчик для вашей платформы и научиться его использовать, потому что программирование на ассемблере без отладчика похоже на попытку собрать робота с завязанными глазами,Вы можете сделать это, но это гораздо сложнее и требует много навыков и опыта.Это ваша главная проблема сейчас, стиль кода и эффективность вашего кода - это как 10% вашей проблемы, а невозможность отладки вашего кода - это 90%.

...