0

How can I convert

.text
la  $t2, b
.data
b:  .word   1, 2, 3

into lui and ori? I use MARS assembler and I have tried:

lui $t2, b
ori $t2, $t2, b 

and

lui $t2, 0($b)
ori $t2, $t2, 0($b)

but they did not work.

Minn
  • 5,688
  • 2
  • 15
  • 42
Ben Bitdiddle
  • 25
  • 1
  • 4
  • the first try is in principle correct, but the precise syntax (and how to extract two 16b parts from symbol `b`) depends on the assembler, so what do you use for assembling first? The second is incorrect in principle, you don't want to load memory value into `t2`, `la` is "load address". – Ped7g Feb 24 '19 at 08:22
  • If your assembler supports `%hi` and `%lo` macros then you could use those (e.g. `lui $t2,%hi(b)`. I think GAS supports those, but I don't think SPIM/MARS does. If you don't have any such macros you might just have to use the actual address of `b` (or rather, the high and low parts of the actual address). – Michael Feb 24 '19 at 08:24
  • I use mars as assembler – Ben Bitdiddle Feb 24 '19 at 08:33
  • 2
    there are no "expressions" in MARS assembler, so you must rather calculate and provide final 16 bit immediate values yourself, i.e. if `b` lands at address 0x10010010, the code will be `lui $t2,0x1001` `ori $t2,$t2,0x0010`, but this is very error-prone and "stupid" to be used for real project, as that means you have to organize your `.data` segment manually, and rewrite all relevant code in case you move something elsewhere, which basically voids all the advantages of using assembler, dumbing it down near the writing binary machine code yourself without assembler... – Ped7g Feb 24 '19 at 11:31
  • You can see how pseudo instructions get assembled into basic ones in the debugger window (compare "Basic" vs "Source" columns). But to rewrite the source without pseudo instructions, and managing the addresses manually without symbols = that's good only for educational purpose to better understand what the MARS does for you when used normally, but it's not a good idea (=wasting time for no obvious reason/benefit) to write some real code like that. – Ped7g Feb 24 '19 at 11:35
  • 1
    @Ped7g: The use-case is `lui $t7, %hi(static_data_base_addr)` and then `lw $t0, %lo(a)($t7)` / `lw $t1, %lo(b)($t7)` etc for static data in the same 64k-aligned block. You could just `la $t7, static_data_base_addr` and then `lw` relative to that base, but that results in a 2-instruction `la` unless it's known at assemble-time that the address you chose is 64k-aligned. Of course, if you're using an assembler that doesn't support hi/lo or `lw $t2, c-base($t7)`, then you're kinda screwed. – Peter Cordes Feb 24 '19 at 18:36
  • @PeterCordes yup, I meant it's not sane to write it manually without assembler support. With `%hi/%lo` expressions (or just "oldschool" `>>16` and `&0xFFFF`) there are good uses for that, as you propose one (other obvious one is to reload pointers if you know the upper part of register is still from same block, when you are golfing for size). – Ped7g Feb 24 '19 at 22:43
  • @Ped7g: With fixed-width instructions, golfing for size is the same as optimizing for fewer instructions. On a RISC where almost all instructions have the same low cost, that's usually just plain optimizing. – Peter Cordes Feb 24 '19 at 22:56

0 Answers0