views:

150

answers:

1
       .data
VALS:  .half 0xbead, 0xface
RES:   .space 4
    .text
    la     $t0,VALS
    lh    $t1,($t0)
    lhu    $t2,2($t0)
    sll    $t2,$t2,16
    or    $t2,$t1,$t2
    jal    AVG
    .word  -2
    .word  -6
    la    $t4,RES
       sw  $v0,($t4)
       li     $v0,10
    syscall
AVG:   lw  $v0,($ra)
    lw    $t3,4($ra)
    add    $v0,$v0,$t3
    sra    $v0,$v0,1
    addi   $ra,$ra,8
    jr     $ra

In this MIPS code, what do the .word portions do? My emulator cannot handle data directives in the text section. What do the directives do? And what is the point of doing .word -2 and .word -6, rather than .word -8?

A: 

the directive puts the word value -2 and -6 in the code stream. if you look at the actually binary representation of this chunk, you'll find, in the middle of the instruction encoding, some FFFFFFFEFFFFFFFA, or FEFFFFFFFAFFFFFF depending on endianness.

The assembler will emit 2 words worth of data of value -2 and -6 respectively, nothing like a single word of -8.

If you look at what is at the AVG: label, you'll notice it uses

lw $v0, ($ra)
lw $t3, 4($ra)

That loads 2 words in registers v0 and t3 from the return address (ie where you jumped from, i.e. from the data embedded in the code segment). So... v0 gets -2 in it, and t3 gets -6. Note also how the code segments adds 8 to $ra before returning, to jump over the embedded data.

In short, it's a way of encoding constant values to be loaded in registers as part of the code stream.

Now, what the code then does is add the 2 together, shift right, before returning (I assume implementing Average). It does not make much sense in this specific case to do that much work, when you could simply directly compute the average at compile time (or if you write asm directly, in your head). I assume AVG is supposed to be called from many places, but even then, since it expects its values from the code segment (usually readonly), I fail to see the point to compute math on constant values.

Bahbar