1
votes

I have some basic questions about addressing modes in Assembly.

I'm given the following instruction:

mov 3[R2+], 0x100

, where the first operand, given in index addressing mode, is the destination and the second one, given in memory direct mode, is the source.

The question asks one to rewrite this instruction having only the following addressing modes at disposal:

  • rx register direct
  • [rx] register indirect
  • # immediate addressing

I can use the instructions add, sub and mov.

I already have the solutions, but don't understand some of the steps.

These are the instructions:

add r2, #3

Why do you have to use direct addressing mode here and not [r2]? From what I understand is that with indirect addressing the operand is the address of a register whose content is an address to a memory location that includes the actual value. So if I add 3 to r2, I get an address that points to a different register, don't I? But what I actually want is the value that is located at a a memory location whose address is 3 + the previous value of the address. Can someone explain this to me please?

The next instruction is:

mov r1, #0x100

Which I understand.

mov [r2],[r1]

I don't understand this instruction, however. From what I understand [r2] is the address of a memory location. But why is indirect addressing used on the second operand? R1 includes the address 0x100. So do I get the value that is stored in memory at location 0x100 with [r1]?

I general if I want to obtain a value being given a register rx that contains an address, can I get the value using an expression like [rx]? How do I get the value of e.g. the value that is stored in location [r2] in that case, is there a direct way to obtain the value or do I have to first write the contents (i.e. the address included in r2) in another register say r3 and then use [r3] to get the actual value?

The last instruction is

sub r2, #2

Once again I'm not sure why r2 is used and not [r2]. I hope someone can clarify this for me.

1
"Why do you have to use direct addressing mode here?" - What do you mean? We want to arrange that the constant 3 is stored in register r2; that's how you do that. What other way would you do it?D.W.
"I don't understand this instruction, however." - What don't you understand? Do you understand what the effect of that instruction is? If not, read the instruction manual for the architecture -- it will tell you what the fefect and meaning of every instruction is.D.W.
mov [r2],[r1] looks wrong. also, there's no clue in your exercise - at least none you mentioned - why 0x100 needs to be loaded into another register first, before moving it to address where r2 points to, rather than doing mov [r2], #0x100Deleted User

1 Answers

2
votes

Register direct is used in add r2, #3 because one wants to add 3 to the value in r2 not add three to the value in the memory whose address is in r2. Adding 3 to the value in r2 produces a new address which can be used by a later register indirect operation.

Register direct addressing just retrieves the value in the register (not an address of the register). It might help to imagine that the system used word addressing and mapped registers in memory starting at 0x00, then add r2, #3 would be equivalent to add [0x02], #3 (adding 3 to the value in memory at address 0x02, which is the address of r2) and add [r2], #3 would be equivalent to add [[0x02]], #3 (i.e., double indirection). (The chosen syntax for absolute memory addressing—just using a bare number, with immediates indicated by prefixing #—seems confusing. I have used square brackets for both forms of memory addressing.)

mov [r2], [r1] copies the value in the memory location whose address is in r1 to the memory location whose address is in r2. Since r1 was just loaded with the value 0x100, this is equivalent to mov [r2], [0x100] (or mov [r2], 0x100 in the confusing syntax chosen for the exercise). However 'mov [r2], [0x100]` would be using an unsupported addressing mode.

If memory indirect addressing is not provided (VAX, a very CISCy ISA, provided this; Renesas RX, a modern CISC, does not), to get the value that is pointed to by a pointer (address) in memory, it would be necessary to first load the pointer into a register, as you surmised.