📄 http:^^www.cs.wisc.edu^~cs354-2^cs354^lec.notes^mal.html
字号:
Very much like their SAL equivalents, except that all the operandsare in registers. (No exceptions!) add rd, rs, rt # rd <- rs + rt (2's complement) addi rd, rs, immediate # rd <- rs + immediate example: addi $13, $5, 8 if $5 contains the value 14, then the result in $13 after execution will be the value 22. 16 bits are available for storing the immediate value. It is sign extended to 32 bits and then a 2's comp. add is done. To think about: what does the instruction add $8, $12, $0 do? Answer: copies the value in $12 into $8.I/O instructions----------------There are 3: getc, putc and puts getc is just get on .byte quantities putc is just put on .byte quantities AND, the operand is in a register. examples: putc $18 # prints out the character contained in the # least significant byte of the register getc $9 # gets one character that the user typed, and # places it in the least significant byte of # the register specified. puts can be used one of 2 ways: puts str1 # prints the null terminated string labelled str1 OR puts $13 # prints the null terminated string that begins at # the address contained in the register specified.Here's a sample MAL program.# this simple MAL program reads in 2 characters, figures# out which one is alphabetically first, and prints it out.# register assignments# 8 -- the first character typed by the user# 9 -- the second character typed by the user# 10 -- temporary# 11 -- holds the value of the larger character# 13 -- the address of the newline character constant# 14 -- newline character (a constant) .datanewline: .byte '\n' .text__start: getc $8 # get 2 characters getc $9 la $13, newline # print out newline lb $14, ($13) putc $14 sub $10, $9, $8 # figure out which is larger bgez $10, secondlarger add $11, $8, $0 b printresultsecondlarger: add $11, $9, $0printresult: putc $11end: doneWhat has been ignored so far: how to fit both an opcode and an address in a 32 bit instruction. first. . .how many bits are "needed" for the opcode? the number of unique patterns given by n bits is 2 ** n. So, the problem boils down to deciding how many instructions are necessary (and desired) for a computer. arithmetic ( + - * / ) (how many representations?) logicals (up to 16) shifting branches loads/stores there are possibly 64 enumerated here, so 6 bits should be enough. That leaves 26 left for a 32 bit address specification. Oops! For a load/store instruction, we need a register specification also (where the data is to come from/go to). That leaves only 21 bits for an address specification.a discussion of addressing modes:The original goal of this discussion was to figure out a wayto fit 32 bit addresses into less than 32 bits.The discussion is going to be expanded a bit to talk about thedifferent ways that an instruction could specify where its operandsare.But first, some way to specify a 32 bit address:1. A BAD WAY. Use more than 1 word to specify an instruction. 2 words: the first contains the opcode and other operands the second contains a 32 bit address This method defeats the whole purpose.2. Keep the address needed in a register. Then use a register specification to tell where the address is. The operand is reached by using the address within the register. Other methods are variations on this one:2a. specify 2 registers. The address is obtained by adding the contents of the 2 registers.2b. specify 1 register plus a small constant. The address is obtained by adding the contents of the register plus the constant.3. (Not mentioned in the text.) Specify only a constant (offset). The address is calculated by adding the constant to the value of the current PC.4. Use whatever bits are available to specify the least significant portion of an address. The missing most significant bits can be taking from the PC. This implies that the operand (address of) is located in the same portion of memory as the instruction being executed.The MIPS architecture uses #2b (exclusively) for addressspecification within a load/store instruction. Address specificationfor branch instructions uses a variation of #3.Many computers offer more ways of getting at operands. Thesemethods are called addressing modes. load/store architectures usually have a VERY limited set of addressing modes available memory to memory architectures often offer LOTS of modes. This flexibility often forces these machines to have variable length instructions.Here are some addressing modes. These names have come undercommon usage. REMEMBER, an addressing mode really gives theinformation of where an operand is (its address). An instructiondecides how to use the address. Register. The operand is in the register. Immediate. The operand is contained within the instruction itself. Direct. The address of the operand is contained within the instruction. (This means that extra bits will need to specify a complete address.) Register Direct. The address of the operand is contained within a register given. This is #2. Base Displacement. Also called indexed or relative. The address is the sum of the contents of a register plus a small constant. This is #2b. Indirect. Adds a level of indirection to direct mode. An address is specified within the instruction. The contents of the address are the address of the operand. A variation might be Register Indirect. The initial address is located in a register (instead of in the instruction).A second look at some MAL load and store instructions:Load/Store---------- lw rt, x(rb) # load word place the word at address X + (rb) into the register rt. example: lw $10, 0($9) presuming $9 contains the value 0x00002000, $10 gets the value 0x0011aaee lb rt, x(rb) # load byte place the byte at address X + (rb) into the least significant byte of register rt, and sign extend the value to the rest of the register. example: lb $10, 0($9) on a little endian machine: presuming $9 contains the value 0x00002000, $10 gets the value 0xffffffee sw rt, x(rb) # store word write the contents of register rt to address X + (rb) example: la $11, c2 sw $10, 4($11) $11 gets the value 0x00002004, then the value 0xffffffee is placed into the word of memory at address 0x00002008MAL programming example (SIMULATED)-----------------------# MAL program to print out the alphabet .datastr1: .asciiz "The alphabet:\n"# register assignments# $8 -- the ASCII character code to be printed# $9 -- the ASCII code for 'z', the ending character .text__start: la $10, str1 puts $10 add $8, $0, 97 # $8 gets ASCII code for 'a' add $9, $0, 122 # $9 gets ASCII code for 'z'while: bgt $8, $9, all_done putc $8 add $8, $8, 1 b whileall_done: putc '\n' doneAnother MAL programming example (SIMULATED)-------------------------------# a MAL program to print out the ? of a user-entered integer. .data# promptsstr1: .asciiz "Enter an integer: "str2: .asciiz "The result is "str_error: .asciiz "\nInput error detected. Quitting.\n"newline: .byte '\n'# variablesint_array: .word 0:20 # array to hold integer for printing .text__start: la $8, str1 # print prompt puts $8 lb $10, newline # read characters and calculate li $11, 57 # the integer represented li $12, 48 getc $9get_chars: beq $9, $10, got_int # newline char terminates loop bgt $9, $11, int_error blt $9, $12, int_error sub $13, $9, 48 # convert char to digit mul $14, $14, 10 # int = int * 10 + digit add $14, $14, $13 getc $9 b get_charsint_error: la $8, str_error puts $8 j end_programgot_int:# $14 -- the integer to be printed# $15 -- base address of array holding the integer# $16 -- running address of array element # $17 -- single digit of the integer# $18 -- single character of the integerprint_int: la $8, str2 puts $8 la $15, int_array move $16, $15more_digits: rem $17, $14, 10 sw $17, ($16) add $16, $16, 4 div $14, $14, 10 bgtz $14, more_digits sub $16, $16, 4 bge $16, $15 more_chars # test for result = 0 putc '0' putc $10 # print newlinemore_chars: lw $18, ($16) add $18, $18, 48 putc $18 sub $16, $16, 4 bge $16, $15, more_charsend_program: putc $10 done</pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -