I'd like to figure out how to encode BASIC INSTRUCTION FORMATS referred to in the MIPS Green Sheet
e.g. I'd like to encode the instruction add $t0 $t1, $t2.
I know that the Format is R; opcode will be 0x0; The Funct 0x20.
But how will I get the code for rs, rt, rd and shamt?
The link in the question is mangled. It should be https://inst.eecs.berkeley.edu/~cs61c/resources/MIPS_Green_Sheet.pdf
If you look in the REGISTER NAME, NUMBER, USE, CALL CONVENTION box at the bottom right of page 1 of that PDF, you'll see that the registers with names $t0 through $t7 correspond to the registers numbered 8 through 15. For the instruction you're interested in:
add $t0, $t1, $t2
$t0 is the destination register, specified by the rd field in the instruction. Since $t0 is register number 8, put 01000 into the rd field.
$t1 and $t2 are the source registers, specified by the rs and rt fields in the instruction. Since $t1 is register number 9 and $t2 is register number 10, put 01001 into the rs field and put 01010 into the rt field.
shamt is not used in the add instruction, so fill that field with zeroes.
BTW, that Green Sheet is fine as a reminder of the nitty-gritty details of the instruction set, but something like https://www.cs.ucsb.edu/~franklin/64/lectures/mipsassemblytutorial.pdf will be more helpful if you're just getting started with the MIPS architecture.
Related
How do I resolve obtaining the wrong value in the W-register after a MOVF operation?
I am debugging a code which builds & programs successfully, but does not have the desired result when powered up as part of the circuit and I have noticed that the working register does not contain the right value after a MOVF operation, whilst debugging.
If the value that is being copied to the W-reg is manually written in during debugging, then the code functions as it should.
The following images, I believe, illustrate the my issue quite well.
1. Port definition.
2. LEDportA value of 0x02 is to be moved to the W-reg.
3. After the operation, W-reg contains 0x00, instead of 0x02.
4. Final image shows that LEDportA is the same as LATA, as it is cleared after the "clrf LEDportA instruction.
I am totally bewildered as to what could be causing it and any insights or advice that anyone can provide will be very much appreciated.
Please note that the PIC MCU in use is the PIC16F1829.
Since you don't provide enough information like PIC model you are using and the rest of the code, as far as I see, your problem is because of wrong bank selection. Your TempC register is located 0x70 in bank 0, and the LATA register is located at 0x10C bank 2 in memory. Thus when you attempt to read the LATA, actually you read the corresponding 0C addres location in bank0. You have to switch the correct bank before you attempt to read or write from any register in RAM. Check the code snippet that has right way to access to the registers. You can switch to a bank either using the BANKSEL directive which is more convenient for programmers or loading a bank value to the BSR (Bank Select Register).
UpdateDisplay:
BANKSEL LEDportA ; Switch to LEDportA bank before any access
MOVF LEDportA, w
andlw 0x0f
BANKSEL TempC ; Switch to TempC bank before any access
movwf TempC
bsf TempC, 4
rrf TempC, F
btfss STATUS, C
bcf TempC, 3
btfsc TempC, 0
....
So far I've written one assembly program that didn't use data memory at all. Now I'm trying to write a super simple program that stores a value then loads that value into a different register (and prints things to make sure I'm sane).
li $t0, 13 # data that I want to store
li $v0, 1
move $a0, $t0
syscall
sw $t0, 0($zero) # error
#lw $t1, 32
#li $v0, 1
#move $a0, $t1
#syscall
I keep getting an 'address out of range' error. I've tried changing the offset to different values (4, 8, 32) and even tried loading immediates into a register so I'm not using the $zero register.
What do I use as a base address if all my program has is data? What is wrong with storing a data value at address zero? My textbook/brain lead me to believe that this was absolutely fine..
That's because there is no memory mapped to address 0. It is most likely somewhere after 0x10000000, (usually 0x10010000 in MARS) in which you will see when you look at the data segment window of the simulator.
So, if you want to access a word at the beginning of the data segment, put a label
ie:
.data
startofdata: .word 0
and in the code section:
la $a0, startofdata
sw $t0, 0($a0)
startdata could be named error, if you wanted to label each location to make it more readable
The first time my PIC30F code reads a word from Data EEPROM, it reads 0xFFFF instead of the data actually in EEPROM. It reads fine afterward.
After a bad read, I checked W1 and it does have the correct address
There are no words in data EEPROM with a value of 0xFFFF
I checked the supply: it's 5.13 V
If I break right before the table read instruction, and step through it, it woks fine
I know that NVMADRU and NVMADR are not involved in reading, but I checked them, and their value doesn't change between good reads and bad reads
It's a dsPIC30F5011
I checked the Errata, and did not find any reference to such issue
I am working through the debug function of MPLAB 8, with a PICkit II
I am working through the debug function of MPLAB 8, with a PICkit II: I reset, then run, and it fails
If I place the code in a tight loop until the value is correct, and counting the number of iterations, I see that it takes 2339 times through the loop until it reads correctly
EEPROM read code:
_ReadEEWord:
;--------------------------------------------------------------------------------
; Read a word from Data EEPROM
; Entry W0 Word address relative to the start of Data EEPROM
; Exit W0 Word at that location
; Uses W1, Table pointer
;--------------------------------------------------------------------------------
; Start address of Data EEPROM
#define DATAEE_START 0x7FFC00
; Setup pointer to EEPROM memory
mov #0x7F,W1 ; Set the table pointer
mov W1,TBLPAG ; to the page with the EEPROM
add W0,W0,W0 ; Convert the word address to a byte address
mov #0xFC00,W1 ; Add the start of EEPROM
add W1,W0,W1 ; to the address
nop
nop
nop
; Return the EEPROM data
tblrdl [W1],W0 ; Read the EEPROM data
nop
nop
nop
return
Any suggestions of what may be causing that?
SOLVED
The documentation doesn't say so, but, before you can read data EEPROM, you must wait for any previous EEPROM operations to be done.
You can do it in one of these ways:
1) In C:
#include <libpic30.h> // Includes EEPROM utilities
_wait_eedata(); // Wait for the erase to be done
2) In C, no lib import
while (NVMCONbits.WR);
3) In assembly:
btsc NVMCON,#15 ; If busy (WR bit s set)
bra $-2 ; Go back and wait
I was looking through an Intel provided reference implementation of RDRAND instruction. The page is Intel Digital Random Number Generator (DRNG) Software Implementation Guide, and the code came from Intel Digital Random Number Generator software code examples.
The following is the relevant portion from Intel. It reads a random value and places it in val, and it sets the carry flag on success.
char rc;
unsigned int val;
__asm__ volatile(
"rdrand %0 ; setc %1"
: "=r" (val), "=qm" (rc)
);
// 1 = success, 0 = underflow
if(rc) {
// use val
...
}
Soory to have to ask. I don't think it was covered in GNU Extended Assembler, and searching for "=qm" is producing spurious hits.
What does the "=qm" mean in the extended assembler?
What you're looking at is an inline assembler constraint. The GCC documentation is at 6.47.3.1 Simple Constraints and 6.47.3.4 Constraints for Particular Machines under x86 family section. This one (=qm) combines three flags which indicate:
=: The operand is write-only - its previous value is not relevant.
q: The operand must be in register a, b, c, or d (it cannot be in esi, for instance).
m: The operand may be placed in memory.
qm probably means 1 byte 8 bit mem
=qm will be valid constraint for storing 1 byte result
See what setc wants
http://web.itu.edu.tr/~aydineb/index_files/instr/setc.html
reg8 and mem8
as we know only eax , ebx edx ecx .. a,b,c,d registers that q refer can be used cause they can accessed with low byte al dl cl ...With combining qm we are getting mem8 . m meant memory. Thats what I meant
Wow that stumped me at first but I searched around a bit and found out that it is a reference to the model of the processor this peice of code is meant for.
Spicically I read that it is for the i7 Quadcore.
Is that where you got this code from?
It is a simple value indicator for a variable syntax.
I just start to program IA-32 assemble and boot loader and I can't understand one command: mov [bootdrv], dl.
dl is the low 8 bits of data register, but I dont know what is [bootdrv]. Is it a variable or something? How could a register be placed in [bootdrv]?
start:
mov ax,0x7c0 ; BIOS puts us at 0:07C00h, so set DS accordinly
mov ds,ax ; Therefore, we don't have to add 07C00h to all our data
mov [bootdrv], dl ; quickly save what drive we booted from
This is the beginning 3 line of a boot loader and [bootdrv] just appear without any definition, I couldn't understand.
Any information would be helpful and appreciated, thank you!
[bootdrv] is a specification of an absolute memory address. The code:
mov [bootdrv], dl
copies the contents of the 8-bit DL register into a byte in memory, at the address resulting of multiplying the current value of DS by 16, then add the value bootdrv. bootdrv itself is a label, which a value that represents where in the current data segment is the memory position located.
On the other hand, the symbol bootdrv must be defined somewhere. Otherwise, the assembler will stop with a "symbol not defined" error. Maybe it's defined past the code (assemblers do two passes through the source code in order to get all symbols so they can be used even if they are defined after the code sequence that uses them). Maybe it's in a separate .INC file.
mov [bootdrv], dl indicates a segment:offset memory access. In the previous instruction, you configured the Data Segment register with an address, so the mov [bootdrv], dl instruction writes to the segment:offset address 0x7c0:bootdrv, whatever bootdrv might be.