Я пытался реализовать линейный алгоритм Брезенхэма в течение нескольких дней, но продолжаю сталкиваться со странными проблемами. Я могу рисовать некоторые линии, но другие просто не работают и приводят к бесконечному циклу. Я потратил часы, пытаясь заставить Qemu работать, и попробовал несколько симуляторов, но, похоже, не могу решить проблему. Ниже приведен код, который должен рисовать саму линию.
drawline:
; r0 = screen_address
; r1 = x0
; r2 = y0
; r3 = x1
; r4 = y1
; r5 = colour
push {r6-r10} ; store the registers we will alter, thoughtful, right?
cmp r1,r3 ; compare x0 and x1
subgt r6,r1,r3 ; deltax = x0 - x1
movgt r7,#-1 ; stepx = -1
suble r6,r3,r1 ; deltax = x1 - x0
movle r7,#1 ; stepx = 1
cmp r2, r4 ; compare y1 and y0
subgt r8,r4,r2 ; deltay = y1 - y0
movgt r9,#-1 ; stepy = -1
suble r8,r2,r4 ; deltay = y0 - y1
movle r9,#1 ; stepy = 1
add r10,r6,r8 ; error = deltax - deltay
line_pixel_loop:
teq r1,r3
teqeq r2,r4
popeq {r6-r10}
bxeq lr
push {r3, lr} ; store registers which we will alter
; the following are inferred:
; r0 = screen address
; r1 = x, current
; r2 = y, current
mov r3,r5 ; colour
bl drawpixel ; draw the pixel
pop {r3, lr} ; restore the altered registers
cmp r8,r10, lsl#1 ; compare deltay (now negative) with 2 * error
addle r10, r8 ; if less than: error += deltay
addle r1, r7 ; if less than: x0 += stepx
cmp r6,r10, lsl #1 ; compare deltax with 2 * error
addge r10, r6 ; if greater than: error += stepx
addge r2, r9 ; if greater than: y0 += stepy
; cmp r1,r3 ; compare x0 and x1
; cmpeq r2,r4 ; if equal: compare y0 and y1
; bne line_pixel_loop ; if not equal, continue the loop
b line_pixel_loop
pop {r6-r10} ; clean up
bx lr ; return
Эти две линии рисуются без проблем:
push {r0-r5}
mov r0,r7 ;screen
mov r1,#300 ;x0
mov r2,#100 ;y0
mov r3,#200 ;x1
mov r4,#200 ;y1
mov r5,r6 ;colour
bl drawline
pop {r0-r5}
push {r0-r5}
mov r0,r7 ;screen
mov r1,#300 ;x0
mov r2,#100 ;y0
mov r3,#400 ;x1
mov r4,#200 ;y1
mov r5,r6 ;colour
bl drawline
pop {r0-r5}
Эта строка не рисуется и не позволяет программе выполняться дальше:
push {r0-r5}
mov r0,r7 ;screen
mov r1,#350 ;x0
mov r2,#265 ;y0
mov r3,#353 ;x1
mov r4,#266 ;y1
mov r5,r6 ;colour
bl drawline
pop {r0-r5}
drawpixel
или вызывающим кодом. Я предполагаю, что это также рукописная сборка (поскольку вы не используете стандартные соглашения о вызовах)? - person Notlikethat   schedule 23.10.2016eq
для условия завершения означает, что если вы перешагнете, вы продолжите до тех пор, пока целое не завершится. Ваш проблемный ввод кажется маленьким deltaX=3, deltaY=1. Если вы перешагнёте точку, ваше завершение никогда не произойдёт. Также r10 (ошибка) только добавляется. Разве это не должно чередоваться между положительным и отрицательным? В соответствии с алгоритмом Wiki breshnam вам необходимо добавить/подписать ошибку (заглавную "Д" там). Вы собираетесь рисовать только один квадрант или предполагается, что он справится со всеми? - person artless noise   schedule 23.10.2016