位图ASM中的颜色特定行

时间:2017-12-01 22:11:47

标签: assembly bitmap mips mars-simulator

我想在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

输出&位图显示的设置: Mips error

我认为问题出现在第19行的某个地方。我能够使用Branch-less比使用特定 n 黄色的所有行。但是我无法使用Branch-equal为一个特定行着色。

标签仅在无分支,而不是分支相等的情况下正确执行。 顺便说一句,它是MIPS ASM。

1 个答案:

答案 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