我想在MARS位图显示中创建一个红色屏幕,而不是让边框变黄。
我首先将第一行和最后一行设为黄色,然后是第一列和最后一列。
这是我的代码:
#MIPS
#ND
#1 b
li $t0, -4 #$t0 holds current iterator
li $s0, 0 #Current COLOMN_iterator
li $s1, 0 #Current ROW_iterator
main:
li $t1, 0x00ff0000 #Loading RED in register
li $t2, 0x00ffff00 #Loading YELLOW in register
addi $gp, $gp, 4 #Incrementing register with one word (next pixel in display)
addi $t0, $t0, 4 #Incrementing current location to next pixel
addi $s0, $s0, 1 #Column++
blt $s1, 1, makePixelYellow #if currentRow == 1
beq $s1, 31, makePixelYellow #if currentRow == 31
j makePixelRed
makePixelYellow:
sw $t2, -4($gp) #Make pixel yellow
bne $s0, 32, main
addi $s1, $s1, 1 #Column finsihed, so row++
li $s0, 0 #Resetting column
j main
makePixelRed:
sw $t1, -4($gp) #Make pixel red
j main
我认为问题出现在第19行的某个地方。我能够使用Branch-less比使用特定 n 黄色的所有行。但是我无法使用Branch-equal为一个特定行着色。
标签仅在无分支,而不是分支相等的情况下正确执行。 顺便说一句,它是MIPS ASM。
答案 0 :(得分:2)
Jester的回答:当你转移到makePixelRed
代码时,你不会更新行/列。
我对计算机图形编程的一般建议:
通常在编写某些像素图形时,您不希望按像素分支,这在性能方面非常昂贵,而代码针对的是性能相反,而是发出更多代码 - 覆盖不同情况的路径,以最小的分支来绘制所需的输出。
"计算一些东西+分支很多+绘制单个像素+循环"仅在性能不重要时才使用,但是你想要只有单个通用代码用于像素绘制和循环(如列/行前进,这实际上可以避免你的错误,如果你只使用这些分支设置黄色/ red像素,然后返回一些" main"结束以完成循环代码),就像在一些光线跟踪器代码中一样,或者在最小二进制大小编码时(256B介绍通常使用这种架构,一个相当用于计算像素颜色的复杂公式然后单个setPixel代码和loop =它的速度很慢,但是由于没有多个setPixel副本,它可以节省很多字节。)
这是一些更直接的"设置黄色边框+红色身体"我的例子(用MARS 4.5测试,延迟分支关闭,我使用了与你相同的Bitmap设置(16x16单位,512x256显示,这意味着32x16位图目标.. UX FTW!)
li $t1, 0x00ff0000 #Loading RED in register
li $t2, 0x00ffff00 #Loading YELLOW in register
big_loop:
# top row + first column
move $a0, $gp # pointer to write to
li $a1, 33 # 32 pixels for first row, +1 for left column
move $a2, $t2 # yellow
jal setPixels
# 14 red rows with yellow endings+starts
li $t0, 14
red_rows_loop:
li $a1, 30
move $a2, $t1
jal setPixels # set 30 red pixels in middle
sw $t2, ($a0) # set 1 yellow at end, and 1 at start of next row
sw $t2, 4($a0)
addi $a0, $a0, 8
addi $t0, $t0, -1
bnez $t0, red_rows_loop
# finish last row to be full yellow
li $a1, 31 # 31 pixels more needed (1 is already there)
move $a2, $t2 # yellow
jal setPixels
li $v0, 32 # MARS service delay(ms)
li $a0, 40 # 40ms = ~25 FPS if the draw would be instant
syscall
addiu $t1, $t1, 0xFE0408 # adjust main color (red -2, green +4, blue +8 + overflows (B -> G -> R)
andi $t1, $t1, 0xFFFFFF # force "alpha" to zero
j big_loop # infinite loop will animated colours...
# Sets $a1 pixels to $a2 value starting at $a0 (memory fill)
# a0 = pointer to write to, a1 = count of pixels, a2 = value of pixel to set
# a0 will be updated to point right after the last written word
setPixels:
sw $a2, ($a0) # set pixel (or simply memory word)
addi $a0, $a0, 4 # advance memory pointer
addi $a1, $a1, -1 # count-down loop
bnez $a1, setPixels
jr $ra # return