Стек и подпрограммы
- Стек:
- Стек
- Стек MIPS
- 0x7FFF FFFF
- растет вниз
- Регистр указателя стека
1 # Evaluate the expression ab - 12a + 18b - 7 2 # 3 # Settings: Load delays OFF; Branch delays OFF, 4 # Trap file ON; Pseudoinstructions ON 5 6 .globl main 7 8 main: 9 lw $t0,a # get a 10 lw $t1,bb # get b 11 mul $t0,$t0,$t1 # a*b 12 subu $sp,$sp,4 # push a*b onto stack 13 sw $t0,($sp) 14 15 lw $t0,a # get a 16 li $t1,-12 # 17 mul $t0,$t0,$t1 # -12a 18 subu $sp,$sp,4 # push -12a onto stack 19 sw $t0,($sp) 20 21 lw $t0,bb # get b 22 li $t1,18 # 23 mul $t0,$t0,$t1 # 18b 24 subu $sp,$sp,4 # push 18b onto stack 25 sw $t0,($sp) 26 27 li $t1,-7 # init sum to -7 28 lw $t0,($sp) # pop 18b 29 addu $sp,$sp,4 30 addu $t1,$t1,$t0 # 18b -7 31 32 lw $t0,($sp) # pop -12a 33 addu $sp,$sp,4 34 addu $t1,$t1,$t0 # -12a + 18b -7 35 36 lw $t0,($sp) # pop ab 37 addu $sp,$sp,4 38 addu $t1,$t1,$t0 # ab - 12a + 18b -7 39 40 done: li $v0,1 # print sum 41 move $a0,$t1 42 syscall 43 li $v0,10 # exit 44 syscall 45 46 .data 47 a: .word 0 48 bb: .word 10
- Аппаратный стек
- Подпрограммы:
- повторное использование
- модульность
- проблема возврата
- аппаратная поддержка:
- инструкции - "jal" и "jr"("jalr")
- особая роль регистра $31($ra)
- Конвенции о вызове:
- вызывающий и и вызываемый
- правила сохранения и использования регистров
- Простая конечная подпрограмма:
- Простая конвенция о вызове:
- Подпрограмма вызывается с помощью инструкции "jal"(которая сохранит обратный адрес в регистре $ra).
- Подпрограмма не будет вызывать другую подпрограмму(конечная).
- Подпрограмма возвращает управление вызывающей программе с помощью инструкции "jr $rа".
- Регистры используются следующим образом:
- $t0 - $t9 - подпрограмма может изменить эти регистры.
- $s0 - $s7 - подпрограмма не должны изменять эти регистры.
- $а0 - $a3 - эти регистры содержат аргументы для подпрограммы. Подпрограмма может изменить их.
- $v0 - $v1 - эти регистры содержат значения, возвращаемые из подпрограммы.
- Основная программа возвращает управление с помощью системного вызова(syscall) 10.
1 # addthree.asm --- read in three integers and print their sum 2 # 3 # This program uses simple linkage. 4 # 5 # Settings: Load delays ON; Branch delays ON 6 # Trap file ON; Pseudoinstructions ON 7 # 8 9 .text 10 .globl main 11 main: 12 jal pread # read first integer 13 nop # 14 move $s0,$v0 # save it in $s0 15 16 jal pread # read second integer 17 nop # 18 move $s1,$v0 # save it in $s1 19 20 jal pread # read third integer 21 nop # 22 move $s2,$v0 # save it in $s2 23 24 addu $s0,$s0,$s1 # compute the sum 25 addu $a0,$s0,$s2 26 27 li $v0,1 # print the sum 28 syscall 29 30 li $v0,10 # exit 31 syscall 32 33 34 # pread -- prompt for and read an integer 35 # 36 # on entry: 37 # $ra -- return address 38 # 39 # on exit: 40 # $v0 -- the integer 41 42 .text 43 .globl pread 44 pread: 45 la $a0,prompt # print string 46 li $v0,4 # service 4 47 syscall 48 49 li $v0,5 # read int into $v0 50 syscall # service 5 51 52 jr $ra # return 53 nop # 54 55 .data 56 prompt: 57 .asciiz "Enter an integer: "
- Простая конвенция о вызове: