[英]What causes this code to output multiple lines (mips assembly)?
注意:請不要拒絕這個新手的問題以幫助學習。 對於某位尋求幫助的人來說,這簡直令人沮喪。
嗨,我一直在嘗試在mips匯編中實現bresenham的算法,但是我使用的是不完整的算法,即不包括錯誤等。我偶然發現了使用該算法的某人的mips匯編代碼,但是我不明白代碼中的什么使程序輸出多行。 main_for是導致代碼輸出多行的一部分嗎?
.data
bitmap : .word 0x10040000
bitmap_x_max : .word 256 # width in pixels
bitmap_y_max : .word 256 # heigh in pixels
s_zero : .float 0.0
s_meio : .float 0.5
s_neg_one : .float -1.0
w_one: .word 1
w_neg_one: .word -1
w_two: .word 2
w_68: .word 256
.text
#valores fixos em cada chamda, values fixed
li $a0, 32
li $a1, 32
addi $sp, $sp, -4
li $t0, 0x000FFFFF
sw $t0, 0($sp)# coloca cor na pilha, saves colour to memory
move $t0, $zero #i = 0
lw $s0, w_68 #final do loop
main_for:
slt $t1, $t0, $s0 #atual < máximo?
beqz $t1, main_for_end
li $a0, 128
li $a1, 128
move $a2, $t0
li $a3, 0
jal desenhaLinha_bom
addi $t0, $t0, 32
j main_for
main_for_end:
li $t0, 0x00000FFF
sw $t0, 0($sp)# coloca cor na pilha, saves colour to stack?
move $t0, $zero #i = 0
lw $s0, w_68 #final do loop
main_for2_end:
li $v0, 10
syscall
SetPixel:
#recebe posicaoo x em $a0, y em $a1 e cor em $a2
# x position is in $a0, y position is in $a1, colour is in $a2
# pinta o bit_map com a cor indicada no pixel indicado, paint bit_map with colour indicated
addi $sp, $sp, -8
sw $t0, 4($sp)
sw $t1, 0($sp)
lw $t0, bitmap # endereco base, base address
lw $t1, bitmap_x_max# x_max: n de colunas maxima, bitmap width
# t1 = y*n_linhas
mult $a1, $t1
mflo $t1 # t1 = y*colunas
# t1 = y*n_colunas + x
add $t1, $t1, $a0 # t1 = y*n_colunas + x
sll $t1, $t1, 2 # t1 = 4*(y*n_colunas + x)
add $t1, $t1, $t0# t1 = base + 4*(y*n_colunas + x)
sw $a2, 0($t1)
lw $t0, 4($sp)
lw $t1, 0($sp)
addi $sp, $sp, 8
jr $ra
desenhaLinha_bom:
#desenha uma linha de (x0,y0)=(a0,a1) ate (x1,y1)=(a2,a3)
#a cor esta em 0($sp) , colour is at 0($sp)
#altera fp! CUIDADO!!!, be careful using $fp
move $fp, $sp # guarda ponto inicial da pilha, save starting point
addi $sp, $sp, -52 # abre espaco para 5 variaveis a serem restauradas
sw $t4, 48($sp)
sw $t3, 44($sp)
sw $t2, 40($sp)
sw $t1, 36($sp)
sw $t0, 32($sp)
sw $s6, 28($sp)
sw $s5, 24($sp)
sw $s4, 20($sp)
sw $s3, 16($sp)
sw $s2, 12($sp)
sw $s1, 8($sp)
sw $s0, 4($sp)
sw $ra, 0($sp)
# register | variable
# | registrador | variável |
# | t0 | x_atual |
# | t1 | y_atual |
# | t2 | erro_atual |
# | t3 | erro_2|aux1 |
# | t4 | aux2 |
# | s0 | cor |
# | s1 | x_final |
# | s2 | y_final |
# | s3 | dx |
# | s4 dy|-dy |
# | s5 | sx |
# | s6 | sy |
lw $s0, 0($fp) #carrega a cor em s0, colour is in $s0
#calcula DX e DY, calculate dx and dy
sub $s3, $a2, $a0 #s3 = x1 - x0
abs $s3, $s3 #s3 = dx = |x1 - x0|
sub $s4, $a3, $a1 #s2 = y1 - y0
abs $s4, $s4 #s4 = dy = |y1 - y0|
# if x0 < x1 then sx := 1 else sx := -1
slt $t0, $a0, $a2 # t0 = (x0 < x1)?
beq $t0, $zero, desenhaLinha_if1_else
desenhaLinha_if1_then:
lw $s5, w_one
j desenhaLinha_if1_exit
desenhaLinha_if1_else:
lw $s5, w_neg_one
desenhaLinha_if1_exit:
# if y0 < y1 then sy := 1 else sy := -1
slt $t0, $a1, $a3 # t0 = (y0 < y1)?
beq $t0, $zero, desenhaLinha_if2_else
desenhaLinha_if2_then:
lw $s6, w_one
j desenhaLinha_if2_exit
desenhaLinha_if2_else:
lw $s6, w_neg_one
desenhaLinha_if2_exit:
sub $t2, $s3, $s4 # err := dx-dy
lw $t0, w_neg_one
mult $t0, $s4
mflo $s4 # s4 = -dy
move $t0, $a0 # t0 = x = x0 (estado inicial)
move $t1, $a1 # t1 = y = y0 (estado inicial)
move $s1, $a2 # s1 = x1 (x_fim)
move $s2, $a3 # s2 = y1 (y_fim)
desenhaLinha_for1:
#plot(x0,y0)
move $a0, $t0
move $a1, $t1
move $a2, $s0
jal SetPixel # plot(x_atual, y_atual)
#testa saida do loop
sub $t3, $s1, $t0 #t3 = x_final - x_atual
sub $t4, $s2, $t1 #t4 = y_final - y_atual
add $t3, $t3, $t4 #se (x_atual == x_final) && (y_atual == y_final), t3 = 0
beqz $t3, desenhaLinha_for1_end # if x0 = x1 and y0 = y1 exit loop
lw $t3, w_two
mult $t3, $t2
mflo $t3 #t3 = err2 = 2*Erro_atual
slt $t4, $s4, $t3 # -dy < err2 ?
beqz $t4, desenhaLinha_for1_if1_end
desenhaLinha_for1_if1_then:
add $t2, $t2, $s4 # t2 = erro_atual = #erro_atual + (-dy)
add $t0, $t0, $s5 # x_atual += sx
desenhaLinha_for1_if1_end:
slt $t4, $t3, $s3 # err2 < dx ?
beqz $t4, desenhaLinha_for1_if2_end
desenhaLinha_for1_if2_then:
add $t2, $t2, $s3 # t2 = erro_atual = erro_atual + dx
add $t1, $t1, $s6 # y_atual += sy
desenhaLinha_for1_if2_end:
j desenhaLinha_for1 #loop
desenhaLinha_for1_end:
lw $t4, 48($sp)
lw $t3, 44($sp)
lw $t2, 40($sp)
lw $t1, 36($sp)
lw $t0, 32($sp)
lw $s6, 28($sp)
lw $s5, 24($sp)
lw $s4, 20($sp)
lw $s3, 16($sp)
lw $s2, 12($sp)
lw $s1, 8($sp)
lw $s0, 4($sp)
lw $ra, 0($sp)
addi $sp, $sp, 52
jr $ra
offtopic:您不應該通過使用Bresenham的算法來學習MIPS,不應該從較小的算法入手,否則當您需要解釋各個指令的作用時將很難為您提供幫助。
ontopic:是的,您是正確的,main_for是代碼繪制多行的地方,w_68控制着多少行(循環執行了多少次)。 w_68存儲在$ s0中,並在每個循環中與$ t0比較(以0初始化,並在小於$ s0時遞增(w_68)。
desenhaLinha_bom是繪制線條的地方(實際為Bresenham)。 尚未檢查在那里實現的完整算法,但是如果可以的話,它是Bresenham算法的改進版本(不是幼稚的算法,因為它是在單個循環中合並八位元組,因此將更難掌握)
希望能幫助到你!
(必須要有一種比試圖找出評論很少的源代碼清單更有效的學習(MIPS)匯編的方法。)
讓我們假設標簽是入口點的候選者,而例程將執行其名稱所建議的操作。
SetPixel: x/y position in $a0/$a1, colour in $a2
從desenhaLinha_bom: line from (x0,y0)=(a0,a1) to (x1,y1)=(a2,a3), colour is at 0($sp)
(通過設置單獨的PIXEL畫一條線)(根據cjj20的注釋,cjj20指出了很多)。
desenhaLinha_bom
僅在第一個.text
(大概開始執行的地方)的代碼中被調用到li $v0, 10 syscall
,這可能會終止它; 在名為main_for:
的標簽與向后跳轉之間。 在此(“主”)循環的開頭,將t0
(初始化為0-current_x?)與s0/w_68
(出於相等性,除了防御性,它看上去是相等的)進行比較。 畫完線之后, t0
/ current_x會增加32,這可能等於或不等於s0/w_68
。
(因此,我認為cjj20假設main_for
負責多行是正確的。)
(您可能會注意到至少兩個完全相似的答案-幾分鍾后,數小時后。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.