Giới thiệu PCSPim

Chia sẻ: Nguyen Van Nhan | Ngày: | Loại File: PDF | Số trang:26

0
128
lượt xem
31
download

Giới thiệu PCSPim

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

PCSpim là chương trình chạy và mô phỏng chương trình hợp ngữ dành cho MIPS. Sau khi cài đặt PCSpim và chạy chương trình (Start - All Programs - PCSpim.exe), cửa sổ chương trình PCSpim hiện lên như hình 1. Hình 1: Cửa sổ chương trình PCSpim Cửa sổ hiển thị chia làm 4 phần: Phần trên cùng hiển thị nội dung của 32 thanh ghi của CPU và FPU. Nội dung sẽ tự động cập nhật khi chương trình hợp ngữ chạy. • Phần dưới kế tiếp hiển thị mã của chương trình ở dạng hợp ngữ, dạng mã máy (số...

Chủ đề:
Lưu

Nội dung Text: Giới thiệu PCSPim

  1. 1. Giới thiệu PCSPim PCSpim là chương trình chạy và mô phỏng chương trình hợp ngữ dành cho MIPS. Sau khi cài đặt PCSpim và chạy chương trình (Start -> All Programs -> PCSpim.exe), cửa sổ chương trình PCSpim hiện lên như hình 1. Hình 1: Cửa sổ chương trình PCSpim Cửa sổ hiển thị chia làm 4 phần: • Phần trên cùng hiển thị nội dung của 32 thanh ghi của CPU và FPU. Nội dung sẽ tự động cập nhật khi chương trình hợp ngữ chạy. • Phần dưới kế tiếp hiển thị mã của chương trình ở dạng hợp ngữ, dạng mã máy (số hex cột thứ 2 từ trái qua), và địa chỉ tương ứng của mỗi lệnh (cột đầu tiên bên trái). • Phần dưới kế tiếp hiển thị dữ liệu khai báo trong chương trình hợp ngữ (ví dụ: mảng hay chuỗi) và dữ liệu trong vùng ngăn xếp khi chương trình hợp ngữ được thực thi. • Phần dưới cùng hiển thị các thông tin phụ của SPIM, thông tin về lỗi nếu có. Chương trình hợp ngữ muốn chạy được phải được load trước. Đế load chương trình hợp ngữ (ở dạng một file có đuôi mở rộng là *.asm hay *.s), thực hiện thao tác File menu -> Open -> chọn file chứa chương trình cần load. Để tạo file *.asm, chúng ta có thể dùng các chương trình soạn thảo thô như Notepad, Notepad++, EditPlus…
  2. Hình 2. Load file chứa chương trình nguồn. Sau khi chương trình hợp ngữ đã được load, chúng ta có thể thực hiện chạy chương trình và quan sát sự thay đối giá trị các thanh ghi, các ô nhớ, vị trí và lệnh đang được thực thi … Các tác vụ chạy chương trình ở trong Simulator menu. Các bước để chạy và quan sát quá trình chạy của chương trình hợp ngữ trên PCSpim: • Chọn Simulator -> Breakpoints… (hoặc nhấn Ctrl+B). Cửa sổ hiện ra điền vào textbox Address giá trị 0x00400000, chọn Add. • Chọn Simulator -> Go (hoặc nhấn F5). Điền giá trị 0x00400000 vào texbox Starting Address, chọn OK. Giá trị của thanh ghi PC lúc này là 0x00400000. • Chọn Simulator -> Single Step (hoặc nhấn F10) để chạy từng dòng lện trong chương trình. Chúng ta có thể quan sát kết quả thực hiện thông qua giá trị của các thanh ghi, các ô nhớ liên quan.
  3. Cách khác để chạy chương trình nguồn: Simularor -> SetValue…, cửa sổ hiện ra, điền vào textbox Register Name giá trị PC, điền vào textbox Value giá trị 0x00400000. Sau đó nhấn F10 để chạy từng bước hay F5 để chạy cho đến khi gặp breakpoints. 2. Các kiến thức cơ sở 2.1 Đổi qua lại giữ số thập lục phân (hexadecimal) và số nhị phân (binary) Số thập lục phân được tạo thành từ 16 ký số: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f. Số nhị phân tạo thành từ 2 ký số: 0, 1. Một ký số thập lục phân tương ứng với số nhị phân gồm 4 ký số theo bảng sau: Ví dụ: Số thập lục phân 0xeca86420 chuyển sang số nhị phân: Số nhị phân 1 0011 0101 0111 1001 1011 1101 1111 chuyển sang số thập lục phân: 2.2 Tổ chức bộ nhớ Bộ nhớ là một mảng 232 ô nhớ 8-bit, bắt đầu từ địa chỉ 0x000000 đến địa chỉ 0xFFFFFFFF. Người dùng chỉ có thể sử dụng vùng nhớ từ 0x00400000 đến 0x7FFFFFFF. Vùng nhớ người dùng chia làm 3 phần: vùng chứa mã (text segment), vùng chứa dữ liệu (data segment)
  4. và vùng nhớ stack (stack segment). Bộ xử lý tương tác với bộ nhớ thông qua việc di chuyển dữ liệu giữa các ô nhớ và các thanh ghi. Có hai thao tác để thực hiện việc di chuyển dữ liệu giữa bộ nhớ và thanh ghi: load và store. Dữ liệu di chuyển được tổ chức thành nhóm một, hai hay bốn byte liên tục nhau theo chiều tăng địa chỉ ô nhớ. • load: nhóm byte liên tục nhau theo chiều tăng địa chỉ ô nhớ bắt đầu từ địa chỉ được chỉ định được copy vào thanh ghi. • store: nhóm dữ liệu 1, 2 byte thấp của thanh ghi hay cả 4 byte của thanh ghi được copy vào bộ nhớ từ địa chỉ được chỉ định. 2.3 Tổ chức thanh ghi MIPS có tấc cả 32 thanh ghi 32-bit có thê sử dụng trong ngôn ngữ assembly được liệt kê trong bảng sau: Bộ xử lý MIPS có bộ tính toán số học/luận lý (ALU) bên trong thực hiện các phép toán số học và luận lý trên số nguyên 32-bit. Phép toán thực hiện bởi ALU gồm hai toán hạng. Một toán hạng là số nguyên chứa trong thanh ghi, toán hạng còn lại có thể chứa trên thanh ghi hay là một phần của lệnh thực hiện phép toán (hằng số). Kết quả của phép toán luôn đặt vào thanh ghi.
  5. 3. Tập lệnh của MIPS Lệnh Cú pháp Định dạng lệnh Ý nghĩa Cộng số bù 2 add rd, rs, rt rd
  6. offset, offset là số bù 2 Load byte và mở lbu rd, offset(base) rd byte đã được mở rộng 0 từ rộng số 0 đầu ô nhớ có địa chỉ base + offset, offset là số bù 2 Load half-word lh rd, offset(base) rd 2 byte liên tiếp đã được và mở rộng dấu mở rộng dấu từ ô nhớ có địa chỉ base + offset , offset là số bù 2 Load half-word lhu rd, offset(base) rd 2 byte liên tiếp đã được và mở rộng số 0 mở rộng 0 từ ô nhớ có địa chỉ base + offset, offset là số bù 2 Load hằng vào 16 lui rd, const 2 byte cao của rd 16 bit const bit cao 2 byte thấp của rd 0x0000 Load word lw rd, offset(base) rd word bộ nhớ có địa chỉ base + offset, offset là số bù 2 Chuyển giá trị từ mfhi rd rd hi hi vào thanh ghi Chuyển giá trị từ mflo rd rd lo lo vào thanh ghi Nhân hai số bù 2 mult rs, rt value(hi, lo) rs*rt; rs và rt là hai số bù 2 Nhân hai số multu rs, rt value(hi, lo) rs*rt; rs và rt là không dấu hai số không dấu NOT từng bit nor rd, rs, $0 rd NOT từng bit của rs NOR từng bit nor rd, rs, rt rd NOR từng bit của rs và rt OR từng bit or rd, rs, rt rd OR từng bit của rs và rt OR từng bit với or rd, rs, const rd OR từng bit của rs và hằng 16 bit hằng sau khi mở rộng 0 Lưu byte thấp của sb rs, offset(base) byte ở offset +base byte thấp thanh ghi vào bộ của rs, offset dạng bù 2 nhớ Lưu hai byte thấp sh rs, offset(base) 2 byte ở offset +base 2 byte vào bộ nhớ thấp của rs, offset dạng bù 2 Lệnh nop sll $0, $0, 0 tạo thời gian trễ cần thiết
  7. Dịch trái không sll rd, rs, shft rd rs sau khi dich trái shft dấu bit; 0
  8. 4. Cú pháp của MIPS Assempler Chú thích (comment) chuỗi các từ bắt đầu bằng #, tất cả các từ bắt đầu từ # cho đến cuối dòng đều được bỏ qua. Tên định danh (identifier) là chuỗi các ký tự chữ, số, dấu gạch dưới (_) và dấu chấm (.) không bắt đầu bằng số. Tên không được trùng với các từ dành riêng là opcode của lệnh. Các ví dụ về tên định danh hợp lệ: main, loop, end_if, case1.2 Các ví dụ về tên định danh không hợp lệ: 1value # số đứng đầu b # trùng với opcode lệnh nhảy add # trùng với opcode lệnh cộng Nhãn bao gồm tên định danh theo sau là dấu hai chấm (:) được đặt ở đầu dòng. Ví dụ: .data item: .word 1 .text .globl main # must be global main: … Số (number) mặc định là cơ số 10. Số thập lục phân (hexadecimal) thêm 0x vào phía trước. Hai số 256 và 0x100 diễn tả số có cùng giá trị. Chuỗi (string) được đặt giữa hai dấu nháy kép (“). Ví dụ: “Hello world!\n”. Các ký tự đặt biệt cho phép trong chuỗi: newline \n tab \t quote \” Chỉ thị (directive) được hỗ trợ gồm có: Tên chỉ thị Ý nghĩa .text Tất cả các phần theo sau cho tới chỉ thị mới (.text, .ktext, .data, .kdata) được đặt trong vùng nhớ chương trình (code segment). Tham số addr nếu có quy định địa chỉ bắt đầu của vùng nhớ chương trình dùng để lưu các phần trong phân đoạn mã chương trình này. Phần theo sau thường là các lệnh. .ktext Tất cả các phần theo sau cho tới chỉ thị mới (.text, .ktext, .data, .kdata) được đặt vào vùng nhớ nhân (kernel) của hệ điều hành. Tham số addr nếu có quy định địa chỉ bắt đầu của vùng nhớ dùng để lưu. Phần theo sau thường là các lệnh. .globl sym Khai báo nhãn sym là toàn cục và có thể được tham khảo từ file khác .data Tất cả các phần theo sau cho tới chỉ thị mới (.text, .ktext, .data, .kdata) được đặt trong vùng nhớ dữ liệu nhân (kernel data segment). Tham số addr nếu có quy định địa chỉ bắt đầu của vùng nhớ dùng để lưu.
  9. .kdata Tất cả các phần theo sau cho tới chỉ thị mới (.text, .ktext, .data, .kdata) được đặt trong vùng nhớ dữ liệu (data segment). Tham số addr nếu có quy định địa chỉ bắt đầu của vùng nhớ dùng để lưu. .ascii str Lưu chuỗi str vào bộ nhớ, không có ký tự kết thúc chuỗi (giá trị = 0) sau cùng .asciiz str Lưu chuỗi str vào bộ nhớ, thêm ký tự kết thúc chuỗi (giá trị = 0) sau cùng .byte b1,..,bn Lưu n byte liên tiếp nhau b1,..,bn vào bộ nhớ .half h1,..,hn Lưu n phần tử 16-bit liên tiếp nhau h1,..,hn vào bộ nhớ .word w1,..,wn Lưu n phần tử 32-bit liên tiếp nhau w1,..,wn vào bộ nhớ .float f1,..,fn Lưu n số thực dấu chấm động độ chính xác đơn liên tiếp nhau f1,..,fn vào bộ nhớ .double d1,..,dn Lưu n số thực dấu chấm động độ chính xác đơn liên tiếp nhau d1,..,dn vào bộ nhớ .space n Cấp phát n byte liên tiếp nhau trong phân đoạn dữ liệu hiện tại. Phải đặt sau chỉ thị .data .extern sym n Khai báo dữ liệu lưu ở sym có kích thước n byte và sym là nhãn toàn cục. Dữ liệu vùng nhớ này được truy xuất thông qua thanh ghi $gp
  10. 5. Các chương trình mẫu 5.1 Các lệnh luận lý: and ori nor andi xor sll or xori srl Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine ON, Allow Pseudo Instructions OFF, Load Trap File OFF, Delayed Branches ON, Delayed Loads ON, Mapped IO OFF, Quiet OFF ## Put the bit pattern 0x0000FACE into register $1. .text .globl main main: ori $1,$0,0xFACE # 0x0000FACE into $1 andi $2,$1,0x0F0F # 0x0A0E in $2 andi $3,$1,0x00F0 # 0x00C0 in $3 sll $3,$3,8 # 0xC000 in $3 or $2,$2,$3 # 0xCA0E in $2 andi $3,$1,0xF000 # 0xF000 in $3 srl $3,$3,8 # 0x00F0 in $3 or $2,$2,$3 # 0xCAFE in $3 # done ## End of file 5.2 Các lệnh số học: add addu div multu addi sub divu mfhi addiu subu mult mflo Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine ON, Allow Pseudo Instructions OFF, Load Trap File OFF, Delayed Branches ON, Delayed Loads ON, Mapped IO OFF, Quiet OFF
  11. ## Program to calculate 3x**2 + 5x - 8 ## ## Assumes that all results fit into 32 bits. ## ## Follows the hardware rule of keeping a new mult ## two instructions away from a previous mflo. ## ## Register Use: ## $8 x ## $9 result .text .globl main main: addiu $8, $0, 1 # put x into $8 mult $8, $8 # lo = x**2 mflo $9 # $9 = x**2 ori $7, $0, 3 # $7 = 3 ori $6, $0, 5 # $6 = 5 mult $7, $9 # lo = 3x**2 mflo $9 # $9 = 3x**2 ori $7, $0, 5 # $7 = 5 addi $9, $9, -8 # $9 = 3x**2 - 8 mult $7, $8 # lo = 5x mflo $7 # $7 = 5x addu $9, $9, $7 # $9 = 3x**2 + 5x - 8 ## End of file 5.3 Các lệnh thao tác bộ nhớ lb lui sb lbu lw sh lh lhu sw Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine ON, Allow Pseudo Instructions OFF, Load Trap File OFF, Delayed Branches ON, Delayed Loads ON, Mapped IO OFF, Quiet OFF
  12. ## copy $9 to memory in big-endian form ## ## Register Use: ## $8 --- first byte of the tape block ## $9 --- 4-byte integer .text .globl main main: lui $9,0x1234 # put data in $9 ori $9,0x5678 # lui $8,0x1000 # $8 is base register sb $9,3($8) # least significant byte srl $9,$9,8 # move next byte to low order sb $9,2($8) # bits 8-15 srl $9,$9,8 # move next byte to low order sb $9,1($8) # bits 16-23 srl $9,$9,8 # move next byte to low order sb $9,0($8) # most significant byte .data tape: # base register points here .space 1024 # tape buffer (1K bytes) ## End of file 5.4 Các lệnh nhảy j bne slti beq bltz sltu bgez slt sltiu Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine ON, Allow Pseudo Instructions OFF, Load Trap File OFF, Delayed Branches ON, Delayed Loads ON, Mapped IO OFF, Quiet OFF ## Find the Significant bits in a pattern ## The significant bits are the leftmost one bit and ## all its to its right ## Approach: Count the number of right shifts needed ## before the pattern becomes all zeros ## ## Register Use: ## $7 --- shift count ## $8 --- the bit pattern, 0x00298D7D for example. .text .globl main main: ori $8,$0,0x0029 # load $8 with the pattern sll $8,$8,16 # shift into MSBs ori $8,$8,0x8D7D # or in the LSBs
  13. loop: beq $8,$0,exit # done when pattern == 00 sll $0,$0,0 # delay or nop after a branch # or jump instruction srl $8,$8,1 # shift right one bit addu $7,$7,1 # increment shift count j loop # repeat sll $0,$0,0 exit: j exit # sponge for extra cycles sll $0,$0,0 ## End of file 5.5 Các ví dụ xử lý chuỗi, xử lý mảng Các lệnh đã biết cho đến giờ: add div mflo slt, slti addi divu mult sltu, sltiu addiu j multu sra addu lb nor srl and lbu or sub andi lh ori subu beq lhu sb sw bgez lui sh xor bltz lw sll xori bne mfhi Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine ON, Allow Pseudo Instructions OFF, Load Trap File OFF, Delayed Branches ON, Delayed Loads ON, Mapped IO OFF, Quiet OFF ## To Lower Case ## ## ## Write a program that converts the string to all lower case ## characters. Do this by adding 0x20 to each character in the string. ## Register Use: ## ## $8 --- current character ## $10 --- character pointer
  14. .text .globl main main: lui $10,0x1000 # initialize base register of the string lbu $8,($10) # get the first char of the string sll $0,$0,0 loop: beq $8,$0,halt # while ( char != '/0' ) sll $0,$0,0 # addiu $8,$8,0x20 # uncapitalize char sb $8,($10) # replace char in string addiu $10,$10,1 # advance the char pointer lbu $8,($10) # get the next char of the string j loop # end while sll $0,$0,0 halt: j halt # cycle sponge sll $0,$0,0 .data string: .asciiz "ABCDEFGHIJKLMNOP" ## End of file 5.6 Các lệnh mã giả mở rộng move d,s # copy the contents of the source register s to the # destination register d li d,value # load register $d with the positive or negative # integer "value". Value may be a 16 or a 32-bit integer. lw d,exp # Load register $d with the value at address "exp". # "exp" is often a symbolic address. la d,exp # load register $d with the address described by the # expression "exp". "exp" is often a symbolic address. nop # no operation. do nothing for one machine cycle. sw d,exp # Store register $d into the word at address exp. # exp can be any of several expression types # that evaluate to an address mul d,s,t # multiply $s by $t. put the result in $d div d,s,t # divide $s by $t. Put the quotient in $d. Operands are # two's complement. divu d,s,t # divide $s by $t. Put the quotient in $d. Operands are # unsigned. remu d,s,t # divide $s by $t. Put the remainder in $d. Operands are # unsigned. Thiết lập các tham số trong menu Simulator -> Settings: SPIM set Bare Machine OFF, Allow Pseudo Instructions ON, Load Trap File OFF, Delayed Branches ON, Delayed Loads ON, Mapped IO OFF, Quiet OFF. Ví dụ theo sau thực hiện việc tính hóa đơn bữa ăn: tổng phí = tiền thức ăn + 8% tiền thuế +15% tiền phục vụ
  15. ## rest.asm ## ## Total restaurant bill calculator ## ## Register Use: ## ## $s0 meal cost ## $s1 tip rate ## $s2 tax rate ## $s3 total rate ## $s4 tax+tip dollars ## $s5 total bill .globl main # Get meal cost main: li $v0,4 # print prompt la $a0,prompt syscall li $v0,5 # input meal cost syscall move $s0,$v0 # save it in $s0 # Calculations lw $s1,tip # get tip rate lw $s2,tax # get tax rate addu $s3,$s1,$s2 # (tax + tip) in percent mul $s4,$s0,$s3 # mealcost*(total rate) div $s4,$s4,100 # mealcost*(total rate)/100 addu $s5,$s0,$s4 # total bill # Output li $v0,4 # print string la $a0,head1 # "tax plus tip" syscall move $a0,$s4 # get tax+tip li $v0,1 # print integer syscall # li $v0,4 # print string la $a0,head2 # "total cost" syscall move $a0,$s5 # get total li $v0,1 # print integer syscall # li $v0,10 # exit syscall .data tip: .word 15 # tip rate in percent tax: .word 8 # tax rate in percent prompt: .asciiz "Enter food cost: " head1 : .asciiz " Tax plus tip: " head2 : .asciiz "\n Total cost: "
  16. 5.7 Các chương trình xử lý xuất nhập SPIM cung cấp các hàm hệ thống dùng để xử lý các thao tác xuất nhập sau: Công việc Mã trong $v0 Tham số Giá trị trả về print integer 1 $a0 == integer print float 2 $f12 == float print double 3 ($f12, $f13) == double print string 4 $a0 == address of string read integer 5 $v0 == integer read float 6 $f0 == float read double 7 ($f0, $f1) == double read string 8 $a0 == buffer address $a1 == buffer length allocate memory 9 $a0 == number of bytes $v0 == address exit 10 Sau đây là ví dụ sử dụng hàm hệ thống để in chuỗi ký tự và kết thúc chương trình: # hello.asm # .text .globl main main: li $v0,4 # code 4 == print string la $a0,string # $a0 == address of the string syscall # Invoke the exception handler. li $v0,10 # code 10 == exit syscall # Halt the program. .data string: .asciiz "Hello SPIM!\n" # end of file Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine OFF, Allow Pseudo Instructions ON, Load Trap File ON, Delayed Branches ON, Delayed Loads ON, Mapped IO OFF, Quiet OFF Ví dụ sau in ra mẫu thư nhắc nhở trả sách một cách tự động sau khi người dùng nhập tên người mượn sách trả trễ:
  17. # overdue.asm .text .globl main main: # get patron name li $v0,4 # print prompt la $a0,prompt # syscall li $v0,8 # code 8 == read string la $a0,name # $a0 == address of buffer li $a1,24 # $a1 == buffer length syscall # Invoke the operating system. # print the letter li $v0,4 # print greeting la $a0,letter # syscall li $v0,4 # print body la $a0,body # syscall li $v0,10 # exit syscall .data prompt: .asciiz "enter name, followed by comma-enter: " letter: .ascii "\n\nDear " name: .space 24 body: .ascii "\nYour library books are way\n" .ascii "overdue. Please return them\n" .ascii "before we give your name\n" .ascii "to the enforcement squad.\n" # end of file 5.8 Dùng stack tính toán biểu thức Thanh ghi stack pointer ($sp) dùng để quản lý stack. Thanh ghi này chỉ đến phần tử trên đỉnh ở vùng nhớ stack. Khi chương trình bắt đầu chạy, $sp có giá trị khởi tạo 0x7FFFFFFC. Vùng nhớ stack mở rộng xuống dưới đồng nghĩa giá trị thanh ghi $sp giảm đi. Tác vụ PUSH phần tử vào stack tiến hành hai việc: • Thứ nhất, thay đổi giá trị thanh ghi $sp để trỏ đến phần tử đỉnh mới • Thứ hai, lưu giá trị vào vị trí đỉnh mới Tương tự, tác vụ POP phần tử ra stack tiến hành hai việc: • Thứ nhất, lưu giá trị phần tử đỉnh stack vào biến • Thứ hai, thay đổi giá trị thanh ghi $sp trỏ đến phần tử đỉnh mới
  18. # PUSH the item in $t0: addiu $sp,$sp,-4 # point to the place for the new item, sw $t0,($sp) # store the contents of $t0 as the new top. # POP the item into $t0: lw $t0,($sp) # Copy top the item to $t0. addiu $sp,$sp,4 # Point to the item beneath the old top. Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine OFF, Allow Pseudo Instructions ON, Load Trap File ON, Delayed Branches ON, Delayed Loads ON, Mapped IO ON, Quiet OFF # Evaluate the expression ab - 12a + 18b - 7 # # Settings: Load delays OFF; Branch delays OFF, # Trap file ON; Pseudoinstructions ON .globl main main: lw $t0,a # get a lw $t1,bb # get b mul $t0,$t0,$t1 # a*b subu $sp,$sp,4 # push a*b onto stack sw $t0,($sp) lw $t0,a # get a li $t1,-12 # mul $t0,$t0,$t1 # -12a subu $sp,$sp,4 # push -12a onto stack sw $t0,($sp) lw $t0,bb # get b li $t1,18 # mul $t0,$t0,$t1 # 18b subu $sp,$sp,4 # push 18b onto stack sw $t0,($sp)
  19. li $t1,-7 # init sum to -7 lw $t0,($sp) # pop 18b addu $sp,$sp,4 addu $t1,$t1,$t0 # 18b -7 lw $t0,($sp) # pop -12a addu $sp,$sp,4 addu $t1,$t1,$t0 # -12a + 18b -7 lw $t0,($sp) # pop ab addu $sp,$sp,4 addu $t1,$t1,$t0 # ab - 12a + 18b -7 done: li $v0,1 # print sum move $a0,$t1 syscall li $v0,10 # exit syscall .data a: .word 0 bb: .word 10 5.9 Cách gọi hàm đơn giản Lệnh jal dùng để gọi hàm, lệnh jr dùng để trở về từ hàm được gọi. Lệnh nop cần được thêm vào sau các lệnh jal và jr jal sub # $ra
  20. $a0 - $a3 — Chứa các tham số cho thủ tục con. Thủ tục con có thể thay đổi các thanh ghi này. $v0 - $v1 — Chứa các giá trị trả về từ thủ tục con. o Thủ tục main trả điều khiển bằng cách sử dụng hàm exit của hệ thống. Thiết lập các tham số trong menu Simulator -> Settings: Bare Machine OFF, Allow Pseudo Instructions ON, Load Trap File ON, Delayed Branches ON, Delayed Loads ON, Mapped IO ON, Quiet OFF Sau đây là chương trình đọc 3 số nguyên và in ra tổng của chúng: # read in three integers and print their sum # .text .globl main main: jal pread # read first integer nop # branch delay slot move $s0,$v0 # save it in $s0 jal pread # read second integer nop # branch delay slot move $s1,$v0 # save it in $s1 jal pread # read third integer nop # branch delay slot move $s2,$v0 # save it in $s2 addu $s0,$s0,$s1 # compute the sum addu $a0,$s0,$s2 li $v0,1 # print the sum syscall li $v0,10 # exit syscall # pread -- prompt for and read an integer # on entry: # $ra -- return address # on exit: # $v0 -- the integer .text .globl pread pread: la $a0,prompt # print string li $v0,4 # service 4 syscall li $v0,5 # read int syscall # service 5 jr $ra # return nop # branch delay slot .data prompt: .asciiz "Enter an integer: "
Đồng bộ tài khoản