0
votes

I am working on a program in MIPS using MARS simulator to read and write .pgm files. It consists of several files containing different helper functions, but for the purposes of this question, there are 2 files of concern: main.asm, and writeimage.asm.

In the .data segment of writeimage.asm, I want to initialize: a string literal "P5\n" a string literal "P2\n" a buffer size, so that I can play with this parameter without having to hardcode a buffer size.

Here is the 'preamble' (if I may call it that) of writeimage.asm:

                  .data
myStack:          .space 5
writeBuffer:      .space 128
                  .align 2
writeBufferSize:  .word 128
                  .align 2
p5:               .ascii "P5\n"
                  .align 2
p2:               .ascii "P2\n"
                  .text
                  .globl write_image
                  write_image: ... 

For some reason, when run my program from main, when I try to access writeBufferSize like so:

la $t0, writeBufferSize
lw $s0, ($t0)

the value loaded into $s0 is zero. Also, the strings p2 and p5 do not seem to exist at the addresses MARS says they are in. Later on in the code I try to write these stings to a file, and when I load the address of the string into $a1 and perform the syscall, what gets printed to the file is nothing; and when I look at the address that is loaded into $a1, and use the debugger to see the contents of that memory address, it's blank, as if the string never existed.

I do not have this issue when I assemble writeimage.asm only, only when I assemble from main, and when I assemble all files in the directory.

I am very frustrated by this, and I really don't want to go hard coding buffer lengths throughout my code. Please help!

Thanks

1

1 Answers

1
votes

Here's my experience:

Scenario A

main.asm:

    .data
    .extern p3, 4   # this will be commented out in some of the other scenarios
    .text
    la $t0, p3
    lw $t1, ($t0)

a.asm:

    .data
    .globl p3       # this will be commented out in some of the other scenarios
p3: .word 200

Build:

  1. Check "Assemble all files in directory"
  2. Open a.asm, and activate the window
  3. Assemble

Result: It works fine, gets the right data value into $t1: 200.

Scenario B

Same as Scenario A except that for build step (2.) activate the window for main.asm instead

Result: It gets an assembler error (hence won't run)!

Apparently, if it sees the .globl first, the .extern in another file is fine, but if it see .extern first, the .globl is considered contradictory.

Scenario C

main.asm: same as Scenario A, except comment out the .extern in main.asm

a.asm: unchanged from Scenario A

Result: both build scenarios like A & B work properly!

Scenario D

main.asm: unchanged from Scenario A (i.e. using .extern)

a.asm: missing (comment out) the .globl directive

Result: No matter which window is activated upon assemble, no assembly errors, but incorrect code.  The label references location 0x10000000, not the proper 0x10010000.  Thus, zero is loaded into $t1.

Apparently the .extern satisfies the assembler, so it silently allows this, even though there is no true definition of the label.


Recommendation: Scenario C — use .globl, but do not use .extern!

Also, the file whose window is activated (foremost) when the assemble button is pushed seems to be the one that goes "first" for .text and .data, so that one will have the simulator entry point, for example — as a result, you want to assemble with your main in the foremost window.