📄 spim.tex
字号:
Store the low halfword from register {\tt Rsrc} at thepossibly-unaligned {\em address\/}.\pinst{usw Rsrc, address}{Unaligned Store Word}Store the word from register {\tt Rsrc} at the possibly-unaligned{\em address\/}.\subsection{Data Movement Instructions}\pinst{move Rdest, Rsrc}{Move}Move the contents of {\tt Rsrc} to {\tt Rdest}.\bigskipThe multiply and divide unit produces its result in two additionalregisters, hi and lo. These instructions move values to and fromthese registers. The multiply, divide, and remainder instructionsdescribed above are pseudoinstructions that make it appear as if thisunit operates on the general registers and detect error conditionssuch as divide by zero or overflow.\inst{mfhi Rdest}{Move From hi}\instX{mflo Rdest}{Move From lo}Move the contents of the hi (lo) register to register {\tt Rdest}.\inst{mthi Rdest}{Move To hi}\instX{mtlo Rdest}{Move To lo}Move the contents register {\tt Rdest} to the hi (lo) register.\bigskipCoprocessors have their own register sets. These instructions movevalues between these registers and the CPU's registers.\inst{mfc{\em z\/} Rdest, CPsrc}{Move From Coprocessor $z$}Move the contents of coprocessor $z$'s register {\tt CPsrc} to CPUregister {\tt Rdest}.\pinst{mfc1.d Rdest, FRsrc1}{Move Double From Coprocessor 1}Move the contents of floating point registers {\tt FRsrc1} and{\tt FRsrc1 + 1} to CPU registers {\tt Rdest} and {\tt Rdest + 1}.\inst{mtc{\em z\/} Rsrc, CPdest}{Move To Coprocessor $z$}Move the contents of CPU register {\tt Rsrc} to coprocessor $z$'sregister {\tt CPdest}.\subsection{Floating Point Instructions}The MIPS has a floating point coprocessor (numbered 1) that operateson single precision (32-bit) and double precision (64-bit) floatingpoint numbers. This coprocessor has its own registers, which arenumbered {\tt \$f0}--{\tt \$f31}. Because these registers are only32-bits wide, two of them are required to hold doubles. To simplifymatters, floating point operations only use even-numberedregisters---including instructions that operate on single floats.Values are moved in or out of these registers a word (32-bits) at atime by {\tt lwc1}, {\tt swc1}, {\tt mtc1}, and {\tt mfc1}instructions described above or by the {\tt l.s}, {\tt l.d}, {\tts.s}, and {\tt s.d} pseudoinstructions described below. The flag setby floating point comparison operations is read by the CPU with its{\tt bc1t} and {\tt bc1f} instructions.In all instructions below, {\tt FRdest}, {\tt FRsrc1}, {\tt FRsrc2},and {\tt FRsrc} are floating point registers (e.g., {\tt \$f2}).\inst{abs.d FRdest, FRsrc}{Floating Point Absolute Value Double}\instX{abs.s FRdest, FRsrc}{Floating Point Absolute Value Single}Compute the absolute value of the floating float double (single) inregister {\tt FRsrc} and put it in register {\tt FRdest}.\inst{add.d FRdest, FRsrc1, FRsrc2}{Floating Point Addition Double}\instX{add.s FRdest, FRsrc1, FRsrc2}{Floating Point Addition Single}Compute the sum of the floating float doubles (singles) in registers{\tt FRsrc1} and {\tt FRsrc2} and put it in register {\tt FRdest}.\inst{c.eq.d FRsrc1, FRsrc2}{Compare Equal Double}\instX{c.eq.s FRsrc1, FRsrc2}{Compare Equal Single}Compare the floating point double in register {\tt FRsrc1} againstthe one in {\tt FRsrc2} and set the floating point condition flagtrue if they are equal.\inst{c.le.d FRsrc1, FRsrc2}{Compare Less Than Equal Double}\instX{c.le.s FRsrc1, FRsrc2}{Compare Less Than Equal Single}Compare the floating point double in register {\tt FRsrc1} againstthe one in {\tt FRsrc2} and set the floating point condition flagtrue if the first is less than or equal to the second.\inst{c.lt.d FRsrc1, FRsrc2}{Compare Less Than Double}\instX{c.lt.s FRsrc1, FRsrc2}{Compare Less Than Single}Compare the floating point double in register {\tt FRsrc1} againstthe one in {\tt FRsrc2} and set the condition flag true if the firstis less than the second.\inst{cvt.d.s FRdest, FRsrc}{Convert Single to Double}\instX{cvt.d.w FRdest, FRsrc}{Convert Integer to Double}Convert the single precision floating point number or integer inregister {\tt FRsrc} to a double precision number and put it inregister {\tt FRdest}.\inst{cvt.s.d FRdest, FRsrc}{Convert Double to Single}\instX{cvt.s.w FRdest, FRsrc}{Convert Integer to Single}Convert the double precision floating point number or integer inregister {\tt FRsrc} to a single precision number and put it inregister {\tt FRdest}.\inst{cvt.w.d FRdest, FRsrc}{Convert Double to Integer}\instX{cvt.w.s FRdest, FRsrc}{Convert Single to Integer}Convert the double or single precision floating point number inregister {\tt FRsrc} to an integer and put it in register {\ttFRdest}.\inst{div.d FRdest, FRsrc1, FRsrc2}{Floating Point Divide Double}\instX{div.s FRdest, FRsrc1, FRsrc2}{Floating Point Divide Single}Compute the quotient of the floating float doubles (singles) inregisters {\tt FRsrc1} and {\tt FRsrc2} and put it in register{\tt FRdest}.\pinst{l.d FRdest, address}{Load Floating Point Double}\pinstX{l.s FRdest, address}{Load Floating Point Single}Load the floating float double (single) at {\tt address} into register{\tt FRdest}.\inst{mov.d FRdest, FRsrc}{Move Floating Point Double}\instX{mov.s FRdest, FRsrc}{Move Floating Point Single}Move the floating float double (single) from register {\tt FRsrc} toregister {\tt FRdest}.\inst{mul.d FRdest, FRsrc1, FRsrc2}{Floating Point Multiply Double}\instX{mul.s FRdest, FRsrc1, FRsrc2}{Floating Point Multiply Single}Compute the product of the floating float doubles (singles) inregisters {\tt FRsrc1} and {\tt FRsrc2} and put it in register{\tt FRdest}.\inst{neg.d FRdest, FRsrc}{Negate Double}\instX{neg.s FRdest, FRsrc}{Negate Single}Negate the floating point double (single) in register {\tt FRsrc}and put it in register {\tt FRdest}.\pinst{s.d FRdest, address}{Store Floating Point Double}\pinstX{s.s FRdest, address}{Store Floating Point Single}Store the floating float double (single) in register {\tt FRdest} at{\tt address}.\inst{sub.d FRdest, FRsrc1, FRsrc2}{Floating Point Subtract Double}\instX{sub.s FRdest, FRsrc1, FRsrc2}{Floating Point Subtract Single}Compute the difference of the floating float doubles (singles) inregisters {\tt FRsrc1} and {\tt FRsrc2} and put it in register{\tt FRdest}.\subsection {Exception and Trap Instructions}\inst{rfe}{Return From Exception}Restore the Status register.\inst{syscall}{System Call}Register {\tt \$v0} contains the number of the system call (seeTable~\ref{tab:syscall}) provided by SPIM.\inst{break n}{Break}Cause exception $n$. Exception 1 is reserved for the debugger.\inst{nop}{No operation}Do nothing.\section{Memory Usage}\begin{figure} \centerline{\psfig{figure=mem.id,height=4in}} \caption{Layout of memory.} \label{fig:mem}\end{figure}The organization of memory in MIPS systems is conventional. Aprogram's address space is composed of three parts (seeFigure~\ref{fig:mem}).At the bottom of the user address space (0x400000) is the textsegment, which holds the instructions for a program.Above the text segment is the data segment (starting at 0x10000000),which is divided into two parts. The static data portion containsobjects whose size and address are known to the compiler and linker.Immediately above these objects is dynamic data. As a programallocates space dynamically (i.e., by {\tt malloc}), the {\tt sbrk}system call moves the top of the data segment up.The program stack resides at the top of the address space(0x7fffffff). It grows down, towards the data segment.\section{Calling Convention}The calling convention described in this section is the one used by{\em gcc\/}, not the native MIPS compiler, which uses a more complexconvention that is slightly faster.\begin{figure} \centerline{\psfig{figure=stack-frame.id,height=4in}} \caption{Layout of a stack frame. The frame pointer points justbelow the last argument passed on the stack. The stack pointer pointsto the last word in the frame.} \label{fig:stack}\end{figure}Figure~\ref{fig:stack} shows a diagram of a stack frame. A frameconsists of the memory between the frame pointer ({\tt \$fp}), whichpoints to the word immediately after the last argument passed on thestack, and the stack pointer ({\tt \$sp}), which points to the lastword in the frame. As typical of Unix systems, the stack growsdown from higher memory addresses, so the frame pointer is above stackpointer.The following steps are necessary to effect a call:\begin{enumerate} \item Pass the arguments. By convention, the first four argumentsare passed in registers {\tt \$a0}--{\tt \$a3} (though simplercompilers may choose to ignore this convention and pass all argumentsvia the stack). The remaining arguments are pushed on the stack. \item Save the caller-saved registers. This includes registers {\tt\$t0}--{\tt \$t9}, if they contain live values at the call site. \item Execute a {\tt jal} instruction.\end{enumerate}Within the called routine, the following steps are necessary:\begin{enumerate} \item Establish the stack frame by subtracting the frame size fromthe stack pointer. \item Save the callee-saved registers in the frame. Register {\tt\$fp} is always saved. Register {\tt \$ra} needs to be saved if theroutine itself makes calls. Any of the registers {\tt \$s0}--{\tt\$s7} that are used by the callee need to be saved. \item Establish the frame pointer by adding the stack frame size - 4to the address in {\tt \$sp}.\end{enumerate}Finally, to return from a call, a function places the returned valueinto {\tt \$v0} and executes the following steps:\begin{enumerate} \item Restore any callee-saved registers that were saved upon entry(including the frame pointer {\tt \$fp}). \item Pop the stack frame by adding the frame size to {\tt \$sp}. \item Return by jumping to the address in register {\tt \$ra}.\end{enumerate}\section{Input and Output}\label{sec:IO}In addition to simulating the basic operation of the CPU and operatingsystem, SPIM also simulates a memory-mapped terminal connected to themachine. When a program is ``running,'' SPIM connects its ownterminal (or a separate console window in {\tt xspim}) to theprocessor. The program can read characters that you type while theprocessor is running. Similarly, if SPIM executes instructions towrite characters to the terminal, the characters will appear on SPIM'sterminal or console window. One exception to this rule is control-C:it is not passed to the processor, but instead causes SPIM to stopsimulating and return to command mode. When the processor stopsexecuting (for example, because you typed control-C or because themachine hit a breakpoint), the terminal is reconnected to SPIM so youcan type SPIM commands. To use memory-mapped IO, {\tt spim} or {\ttxspim} must be started with the {\tt -mapped\_io} flag.The terminal device consists of two independent units: a {\emreceiver\/} and a {\em transmitter\/}. The receiver unit readscharacters from the keyboard as they are typed. The transmitter unitwrites characters to the terminal's display. The two units arecompletely independent. This means, for example, that characterstyped at the keyboard are not automatically ``echoed'' on the display.Instead, the processor must get an input character from the receiverand re-transmit it to echo it.\begin{figure} \centerline{\psfig{figure=io_reg.id,height=4in}} \caption{The terminal is controlled by four device registers,each of which appears as a special memory location at the givenaddress. Only a few bits of the registers are actually used: theothers always read as zeroes and are ignored on writes.} \label{fig:io_reg}\end{figure}The processor accesses the terminal using four memory-mapped deviceregisters, as shown in Figure~\ref{fig:io_reg}. ``Memory-mapped''means that each register appears as a special memory location. TheReceiver Control Register is at location 0xffff0000; only two of itsbits are actually used. Bit 0 is called ``ready'': if it is one itmeans that a character has arrived from the keyboard but has not yetbeen read from the receiver data register. The ready bit isread-only: attempts to write it are ignored. The ready bit changesautomatically from zero to one when a character is typed at thekeyboard, and it changes automatically from one to zero when thecharacter is read from the receiver data register.Bit one of the Receiver Control Register is ``interrupt enable''.This bit may be both read and written by the processor. The interruptenable is initially zero. If it is set to one by the processor, aninterrupt is requested by the terminal on level zero whenever theready bit is one. For the interrupt actually to be received by theprocessor, interrupts must be enabled in the status register of thesystem coprocessor (see Section \ref{sec:mips}).Other bits of the Receiver Control Register are unused: they alwaysread as zeroes and are ignored in writes.The second terminal device register is the Receiver Data Register (ataddress 0xffff0004). The low-order eight bits of this registercontain the last character typed on the keyboard, and all the otherbits contain zeroes. This register is read-only and only changesvalue when a new character is typed on the keyboard. Reading theReceiver Data Register causes the ready bit in the Receiver ControlRegister to be reset to zero.The third terminal device register is the Transmitter Control Register(at address 0xffff0008). Only the low-order two bits of this registerare used, and they behave much like the corresponding bits of theReceiver Control Register. Bit 0 is called ``ready'' and isread-only. If it is one it means the transmitter is ready to accept anew character for output. If it is zero it means the transmitter isstill busy outputting the previous character given to it. Bit one is``interrupt enable''; it is readable and writable. If it is set toone, then an interrupt will be requested on level one whenever theready bit is one.The final device register is the Transmitter Data Register (at address0xffff000c). When it is written, the low-order eight bits are takenas an ASCII character to output to the display. When the TransmitterData Register is written, the ready bit in the Transmitter ControlRegister will be reset to zero. The bit will stay zero until enoughtime has elapsed to transmit the character to the terminal; then theready bit will be set back to one again. The Transmitter DataRegister should only be written when the ready bit of the TransmitterControl Register is one; if the transmitter isn't ready then writes tothe Transmitter Data Register are ignored (the write appears tosucceed but the character will not be output).In real computers it takes time to send characters over the seriallines that connect terminals to computers. These time lags aresimulated by SPIM. For example, after the transmitter startstransmitting a character, the transmitter's ready bit will become zerofor a while. SPIM measures this time in instructions executed, not inreal clock time. This means that the transmitter will not becomeready again until the processor has executed a certain number ofinstructions. If you stop the machine and look at the ready bit usingSPIM, it will not change. However, if you let the machine run thenthe bit will eventually change back to one.\end{document}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -