1

I am a beginner trying to design an assembler for MIPS. Any help would be greatly appreciated.

Suppose I have this assembly file

    main:   lw $a0, 0($t0)
begin:  addi $t0, $zero, 0      # beginning
    addi $t1, $zero, 1
loop:   slt $t2, $a0, $t1       # top of loop
    bne $t2, $zero, finish
    add $t0, $t0, $t1
    addi $t1, $t1, 2
    j loop              # bottom of loop
finish: add $v0, $t0, $zero

I understand that the jump instruction follows the J-type instruction format as follows:

enter image description here

From the instruction format, I got that the target address would be a 26-bits memory address in binary. Please correct me if I am wrong anywhere until this point.

I managed to develop a program that reads the assembly file and pinpoints the labels (i.e. the labels "main" and "loop") and retrieves their corresponding memory addresses.

For example: for the label "loop," it is located at the memory address 00401595.

I was wondering if I could just simply convert that memory address into binary and append it to the opcode of the jump instruction, will I be able to get the correct machine code for the line:

j loop

Or is there another correct way of obtaining the target address for the J-type instruction format?

And also, my professor once told me that I could initialize the program counter to exactly 0. So, I assume that the memory address for "main" would be 0? Is there a way I could do this manually?

Thanks in advance.

Tina
  • 179
  • 1
  • 3
  • 13
  • 1
    The `j` instruction uses word addressing, that is addresses shifted by 2. – Jester Feb 22 '19 at 14:22
  • 2
    Are you sure `loop` is at 00401595? Aren't instructions supposed to be aligned to 4-byte boundaries? – user200783 Feb 22 '19 at 14:22
  • See https://stackoverflow.com/a/36443100/1524450 – Michael Feb 22 '19 at 14:40
  • Address of `main()` is not 0x000. You can look up the address in your binary with `objdump -t a.out | grep main`. If ASLR is enabled, then address is hard to predict statically. – brokenfoot Feb 22 '19 at 14:40
  • @Jester Does that mean that I just need to get the address of "loop," shift it to the left by two bits and then, append it to the opcode of j instruction to get the machine code instruction for that line? – Tina Feb 22 '19 at 15:00
  • @brokenfoot Can I use the same method if I am programming it in C? Because I couldn't make it work. – Tina Feb 22 '19 at 15:02
  • _"Does that mean that I just need to get the address of "loop," shift it to the left by two bits and then, append it to the opcode of j instruction"_ If `loop` meets the requirement of being in the same 256MB region as the instruction directly following the jump instruction, then yes. Otherwise, no. – Michael Feb 22 '19 at 15:11
  • You need to shift it **right** not left. – Jester Feb 22 '19 at 15:19
  • For shifting to make any sense, `loop` really needs to be 4-byte aligned. If it's really 00401595, you've got a more fundamental problem. – user200783 Feb 22 '19 at 15:29
  • @user200783 How exactly do I retrieve the memory address of a word, then? From your answer, I assume that I must be doing it incorrectly... – Tina Feb 22 '19 at 15:30
  • How are you getting the address of `loop` at the moment? – user200783 Feb 22 '19 at 15:31
  • @user200783 This line of code: `void * get_pc () { return __builtin_return_address(0); }` – Tina Feb 22 '19 at 15:33
  • 1
    That makes no sense. That will return the `pc` of the assembler not the assembled code. I assume you are running it on another architecture where it isn't even aligned. – Jester Feb 22 '19 at 15:48

0 Answers0