Bài giảng Kiến trúc máy tính - Chương 3: Kiến trúc tập lệnh (Assembly language)
Các phát biểu trong hợp ngữ MIPS
Khung dạng chương trình hợp ngữ MIPS
Định nghĩa/khai báo dữ liệu
Địa chỉ bắt đầu (alignment) và thứ tự các byte trong bộ nhớ
Các hàm hệ thống
Thủ tục/hàm
Truyền tham số và Runtime Stack
Khung dạng chương trình hợp ngữ MIPS
Định nghĩa/khai báo dữ liệu
Địa chỉ bắt đầu (alignment) và thứ tự các byte trong bộ nhớ
Các hàm hệ thống
Thủ tục/hàm
Truyền tham số và Runtime Stack
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kiến trúc máy tính - Chương 3: Kiến trúc tập lệnh (Assembly language)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.
File đính kèm:
- bai_giang_kien_truc_may_tinh_chuong_3_kien_truc_tap_lenh_ass.pdf
Nội dung text: Bài giảng Kiến trúc máy tính - Chương 3: Kiến trúc tập lệnh (Assembly language)
- dce 2017 Chapter 3.2 Hợp ngữ MIPS (Assembly Language) Kiến trúc Máy tính– Chương 3 © Fall 2017 2
- dce 2017 Các phát biểu trong hợp ngữ MIPS Có 3 loại phát biểu trong hợp ngữ MIPS Bình thường một phát biểu là một dòng 1. Các lệnh thật Là các lệnh trong tập lệnh của bộ xử lý MIPS Tương ứng một lệnh dạng mã máy (số 32 bit) 2. Lệnh giả (Pseudo-Instructions) và Macros Được chuyển sang các lệnh thật bởi assembler Mục đích giảm công sức cho lập trình viên 3. Các chỉ thị (directive) của Assembler Cung cấp thông tin để assembler dịch chương trình Dùng để định nghĩa phân đoạn, cấp phát dữ liệu bộ nhớ Không thực thi được: chỉ thị không phải là lệnh Kiến trúc Máy tính– Chương 3 © Fall 2017 4
- dce 2017 Chú thích (Comments) Chú thích rất quan trọng! Giải thích mục đích của chương trình Giúp việc đọc hiểu chương trình dễ dàng khi viết và xem lại bởi chính mình và người khác Giải thích dữ liệu vào, ra Chú thích cần thiết ở đầu mỗi thủ tục/hàm . Chỉ ra đối số, kết quả của thủ tục/hàm . Mô tả mục đích của thủ tục/hàm Chú thích trên một dòng Bắt đầu với ký tự # Kiến trúc Máy tính– Chương 3 © Fall 2017 6
- dce 2017 Khung dạng mẫu của chương trình hợp ngữ # Title: Filename: # Author: Date: # Description: # Input: # Output: ################# Data segment ##################### .data . . . ################# Code segment ##################### .text .globl main main: # main program entry . . . li $v0, 10 # Exit program syscall Kiến trúc Máy tính– Chương 3 © Fall 2017 8
- dce 2017 Phân chia phân đoạn của chương trình 0x7FFFFFFF Stack Segment Stack Grows Downwards Memory Addresses in Hex Dynamic Area Data Segment Static Area 0x10000000 Text Segment 0x04000000 Reserved 0 Kiến trúc Máy tính– Chương 3 © Fall 2017 10
- dce 2017 Phát biểu khai báo dữ liệu Nằm trong phân đọa dữ liệu .DATA Đánh dấu ô nhớ tương ứng với tên và dữ liệu khởi tạo Cú pháp: [name:] directive initializer [, initializer] . . . var1: .WORD 10 Các giá trị khởi tạo chuyển thành dạng dữ liệu nhị phân trong vùn nhớ dữ liệu tương ứng Kiến trúc Máy tính– Chương 3 © Fall 2017 12
- dce 2017 Các chỉ thị về chuỗi (String Directives) .ASCII Cấp phát các ô nhớ 1 byte cho chuỗi ASCII .ASCIIZ Giống với chỉ thị .ASCII, nhưng thêm ký tự NULL tại vị trí kết thúc chuỗi Ký tụ NULL có giá trị bằng 0, đánh dấu kết thúc chuỗi .SPACE Cấp phát n ô nhớ 1 byte không khởi tạo giá trị trong vùng nhớ dữ liệu Kiến trúc Máy tính– Chương 3 © Fall 2017 14
- dce 2017 Tiếp theo Các phát biểu trong hợp ngữ MIPS Khung dạng chương trình hợp ngữ MIPS Định nghĩa/khai báo dữ liệu Địa chỉ bắt đầu (alignment) và thứ tự các byte trong bộ nhớ Các hàm hệ thống Thủ tục/hàm Truyền tham số và Runtime Stack Kiến trúc Máy tính– Chương 3 © Fall 2017 16
- dce 2017 Bảng ký hiệu (Symbol Table) Assembler tạo bảng ký hiệu cho các biến (label) Assembler tính toán địa chỉ của các biến trong vùng nhớ dữ liệu và lưu vào bảng ký hiệu Ví dụ Symbol Table .DATA Label Address var1: .BYTE 1, 2,'Z' var1 0x10010000 str1: .ASCIIZ "My String\n" str1 0x10010003 var2: .WORD 0x12345678 var2 0x10010010 .ALIGN 3 var3 0x10010018 var3: .HALF 1000 str1 var1 0x10010000 1 2 'Z' 'M' 'y' ' ' 'S' 't' 'r' 'i' 'n' 'g' '\n' 0 0 0 Unused 0x10010010 0x12345678 0 0 0 0 1000 var2 (aligned) Unused var3 (address is multiple of 8) Kiến trúc Máy tính– Chương 3 © Fall 2017 18
- dce 2017 Tiếp theo Các phát biểu trong hợp ngữ MIPS Khung dạng chương trình hợp ngữ MIPS Định nghĩa/khai báo dữ liệu Địa chỉ bắt đầu (alignment) và thứ tự các byte trong bộ nhớ Các hàm hệ thống Thủ tục/hàm Truyền tham số và Runtime Stack Kiến trúc Máy tính– Chương 3 © Fall 2017 20
- dce 2017 Các dịch vụ của Syscall Service $v0 Arguments / Result Print Integer 1 $a0 = integer value to print Print Float 2 $f12 = float value to print Print Double 3 $f12 = double value to print Print String 4 $a0 = address of null-terminated string Read Integer 5 Return integer value in $v0 Read Float 6 Return float value in $f0 Read Double 7 Return double value in $f0 $a0 = address of input buffer Read String 8 $a1 = maximum number of characters to read Allocate Heap $a0 = number of bytes to allocate 9 memory Return address of allocated memory in $v0 Exit Program 10 Kiến trúc Máy tính– Chương 3 © Fall 2017 22
- dce 2017 Ví dụ syscall - Đọc và In số nguyên ################# Code segment ##################### .text .globl main main: # main program entry li $v0, 5 # Read integer syscall # $v0 = value read move $a0, $v0 # $a0 = value to print li $v0, 1 # Print integer syscall li $v0, 10 # Exit program syscall Kiến trúc Máy tính– Chương 3 © Fall 2017 24
- dce 2017 Ví dụ CT1: Tổng ba số nguyên # Sum of three integers # # Objective: Computes the sum of three integers. # Input: Requests three numbers. # Output: Outputs the sum. ################### Data segment ################### .data prompt: .asciiz "Please enter three numbers: \n" sum_msg: .asciiz "The sum is: " ################### Code segment ################### .text .globl main main: la $a0,prompt # display prompt string li $v0,4 syscall li $v0,5 # read 1st integer into $t0 syscall move $t0,$v0 Kiến trúc Máy tính– Chương 3 © Fall 2017 26
- dce 2017 Ví dụ CT2: Đổi chữ thường sang hoa # Objective: Convert lowercase letters to uppercase # Input: Requests a character string from the user. # Output: Prints the input string in uppercase. ################### Data segment ##################### .data name_prompt: .asciiz "Please type your name: " out_msg: .asciiz "Your name in capitals is: " in_name: .space 31 # space for input string ################### Code segment ##################### .text .globl main main: la $a0,name_prompt # print prompt string li $v0,4 syscall la $a0,in_name # read the input string li $a1,31 # at most 30 chars + 1 null char li $v0,8 syscall Kiến trúc Máy tính– Chương 3 © Fall 2017 28
- dce 2017 Ví dụ CT3: Truy xuất File # Sample MIPS program that writes to a new text file .data file: .asciiz "out.txt" # output filename buffer: .asciiz "Sample text to write" .text li $v0, 13 # system call to open a file for writing la $a0, file # output file name li $a1, 1 # Open for writing (flags 1 = write) li $a2, 0 # mode is ignored syscall # open a file (file descriptor returned in $v0) move $s6, $v0 # save the file descriptor li $v0, 15 # Write to file just opened move $a0, $s6 # file descriptor la $a1, buffer # address of buffer from which to write li $a2, 20 # number of characters to write = 20 syscall # write to file li $v0, 16 # system call to close file move $a0, $s6 # file descriptor to close syscall # close file Kiến trúc Máy tính– Chương 3 © Fall 2017 30
- dce 2017 Thủ tục/hàm - Procedure Hàm giúp lập trình viên phân chia chương trình thành các khối chức năng để: Dễ dàng cho việc viết và sửa lỗi Cho phép dùng lại code Hàm giúp lập trình viên tập trung hiện thực một khối chức năng đơn giản tại một thời điểm Các tham số là giao diện giữa hàm và phần còn lại của chương trình, các tham số gồm có đối số truyền cho hàm (arguments) và giá trị trả về (results) Kiến trúc Máy tính– Chương 3 © Fall 2017 32
- dce 2017 Ví dụ trình tự gọi hàm/trở về Giả sử muốn gọi hàm: swap(a,10) 1.Khởi tạo đối số $a0 = địa chỉ của mảng a và $a1=10 2.Lưa địa chỉ trở về vào thanh ghi $31 = $ra, và nhảy đến hàm swap 3,4,5.Hàm swap thực thi công việc 6.Trở về hàm gọi bằng cách nhảy đến địa chỉ đã lư trong thanh ghi $ra (return address) swap: Registers sll $t0,$a1,2 . . . Caller add $t0,$t0,$a0 $a0=$4 addr a la $a0, a lw $t1,0($t0) $a1=$5 10 li $a1, 10 lw $t2,4($t0) jal swap sw $t2,0($t0) . . . # return here sw $t1,4($t0) $ra=$31 ret addr . . . jr $ra Kiến trúc Máy tính– Chương 3 © Fall 2017 34
- dce 2017 Ví dụ viết thủ tục/hàm Xét hàm swap (ngôn ngữ C) Chuyển sang hợp ngữ MIPS void swap(int v[], int k) { int temp; temp = v[k] swap: v[k] = v[k+1]; sll $t0,$a1,2 # $t0=k*4 v[k+1] = temp; add $t0,$t0,$a0 # $t0=v+k*4 } lw $t1,0($t0) # $t1=v[k] Parameters: lw $t2,4($t0) # $t2=v[k+1] $a0 = Address of v[] sw $t2,0($t0) # v[k]=$t2 $a1 = k, and sw $t1,4($t0) # v[k+1]=$t1 Return address is in $ra jr $ra # return Kiến trúc Máy tính– Chương 3 © Fall 2017 36
- dce 2017 Chi tiết lệnh JAL và JR Address Instructions Assembly Language Pseudo-Direct 00400020 lui $1, 0x1001 la $a0, a Addressing 00400024 ori $4, $1, 0 00400028 ori $5, $0, 10 ori $a1,$0,10 PC = imm26<<2 0040002C jal 0x10000f jal swap 0x10000f << 2 00400030 . . . # return here = 0x0040003C swap: $31 0x00400030 0040003C sll $8, $5, 2 sll $t0,$a1,2 00400040 add $8, $8, $4 add $t0,$t0,$a0 Register $31 00400044 lw $9, 0($8) lw $t1,0($t0) is the return 00400048 lw $10,4($8) lw $t2,4($t0) address register 0040004C sw $10,0($8) sw $t2,0($t0) 00400050 sw $9, 4($8) sw $t1,4($t0) 00400054 jr $31 jr $ra Kiến trúc Máy tính– Chương 3 © Fall 2017 38
- dce 2017 Truyền tham số Truyền tham số cho thủ tục/hàm Đưa tấc cả các tham số cần thiết vào vùng lưu trữ mà thủ tục/hàm được gọi có thể truy xuất được Sau đó gọi hàm (jal) Hai loại vùng lưu trữ Thanh ghi: các thanh ghi đa mục đích được sử dụng (phương pháp truyền tham số bằng thanh ghi) Bộ nhớ: vùng nhớ stack (phương pháp truyền tham số bằng stack) Hai cơ chế phổ biến của việc truyền tham số Pass-by-value: giá trị của tham số được truyền Pass-by-reference: địa chỉ của tham số được truyền Kiến trúc Máy tính– Chương 3 © Fall 2017 40
- dce 2017 Truyền tham số . Khi hàm được gọi (callee) cần nhiều hơn số lượng thanh ghi mặc định cho tham số và giá trị trả về? callee sử dụng stack – hàng đợi last-in-first-out • Thanh ghi $sp (29) được sử dụng high addr để giữ địa chỉ của stack (stack “lớn” theo chiều đi xuống) top of stack $sp − thêm dữ liệu vào stack– push $sp = $sp – 4 #mở rộng stack sw data,0($sp)#lưu vào tos − lấy dữ liệu từ stack– pop lw data,0($sp)#lấy dữ liệu low addr $sp = $sp + 4 #chỉnh lại tos Kiến trúc Máy tính– Chương 3 © Fall 2017 42
- dce 2017 Quy ước sử dụng các thanh ghi $a0 – $a3: arguments (reg’s 4 – 7) $v0, $v1: result values (reg’s 2 and 3) $t0 – $t9: temporaries Có thể thay đổi giá trị tùy ý trong hàm $s0 – $s7: saved Phải bảo toàn giá trị khi hàm thực thi lệnh trở về hàm gọi (lưu/phục hồi bằng stack) $gp: global pointer cho dữ liệu tĩnh(reg 28) $sp: stack pointer (reg 29) $fp: frame pointer (reg 30) $ra: return address (reg 31) Kiến trúc Máy tính– Chương 3 © Fall 2017 44
- dce 2017 Các quy ước về gọi hàm - 2 Hàm được gọi Callee phải làm các việc sau: 1. Cấp phát vùng nhớ cho stack frame $sp = $sp – n (n byte cấp phát cho stack frame) Lập trình viên cần xác định n Hàm lá không cần stack frame (n = 0) 2. Lưu các thanh ghi $ra, $fp, $s0 - $s7 vào stack frame $ra, $fp, $s0 - $s7 phải được bảo toàn giá trị trước khi thực hiện việc trở về (return) Trước khi thay đổi giá trị (nếu cần) Thanh ghi $ra cần phải lưu nếu trong hàm gọi một hàm khác (hàm lồng) 3. Cập nhật frame pointer $fp (nếu cần) Các hàm đơn giản, thanh ghi không cần sử dụng $fp Kiến trúc Máy tính– Chương 3 © Fall 2017 46
- dce 2017 Ví dụ hàm lá 1 Hàm lá là hàm không gọi các hàm khác C code: int leaf_example (int g, h, i, j) { int f; f = (g + h) - (i + j); return f; } Arguments g, , j in $a0, , $a3 Result in $v0 Kiến trúc Máy tính– Chương 3 © Fall 2017 48
- dce 2017 Ví dụ hàm lá 2 C code: int leaf_example (int g, h, i, j) { int f; f = (g + h) - (i + j); return f; } Arguments g, , j in $a0, , $a3 f in $s0 (cần phải bảo toàn giá trị trước khi trở về) Result in $v0 Kiến trúc Máy tính– Chương 3 © Fall 2017 50
- dce 2017 Hàm lồng Hàm lồng là hàm có thực hiện gọi hàm khác Địa chỉ trở về trong thanh ghi $ra trong hàm lồng? int rt_1 (int i) { if (i == 0) return 0; else return i + rt_2(i-1); } caller: jal rt_1 next: . . . rt_1: bne $a0, $zero, to_2 add $v0, $zero, $zero jr $ra to_2: addu $t0, $zero, $a0 addi $a0, $a0, -1 jal rt_2 addu $v0, $t0, $v0 jr $ra rt_2: . . . Kiến trúc Máy tính– Chương 3 © Fall 2017 52
- dce 2017 Lưu địa chỉ trở về Hiện thực đúng (i là $a0, giá trị trả về $v0) rt_1: bne $a0, $zero, to_2 add $v0, $zero, $zero high addr jr $ra to_2: addi $sp, $sp, -8 old TOS $sp sw $ra, 4($sp) sw $a0, 0($sp) addi $a0, $a0, -1 jal rt_2 bk_2: lw $a0, 0($sp) lw $ra, 4($sp) low addr addi $sp, $sp, 8 addu $v0, $v0, $a0 $ra jr $ra Lưu địa chỉ trở về (và tham số) trên stack Kiến trúc Máy tính– Chương 3 © Fall 2017 54
- dce 2017 Ví dụ hàm lồng – tính giai thừa MIPS code: fact: addi $sp, $sp, -8 # adjust stack for 2 items sw $ra, 4($sp) # save return address sw $a0, 0($sp) # save argument slti $t0, $a0, 1 # test for n < 1 beq $t0, $zero, L1 addi $v0, $zero, 1 # if so, result is 1 addi $sp, $sp, 8 # pop 2 items from stack jr $ra # and return L1: addi $a0, $a0, -1 # else decrement n jal fact # recursive call lw $a0, 0($sp) # restore original n lw $ra, 4($sp) # and return address addi $sp, $sp, 8 # pop 2 items from stack mul $v0, $a0, $v0 # multiply to get result jr $ra # and return Kiến trúc Máy tính– Chương 3 © Fall 2017 56
- dce 2017 Chuyển một hàm đệ quy fact: addi $sp, $sp, -8 #adjust stack pointer sw $ra, 4($sp) #save return address sw $a0, 0($sp) #save argument n slti $t0, $a0, 1 #test for n =1, go to L1 addi $v0, $zero, 1 #else return 1 in $v0 addi $sp, $sp, 8 #adjust stack pointer jr $ra #return to caller (1st) L1: addi $a0, $a0, -1 #n >=1, so decrement n jal fact #call fact with (n-1) #this is where fact returns bk_f: lw $a0, 0($sp) #restore argument n lw $ra, 4($sp) #restore return address addi $sp, $sp, 8 #adjust stack pointer mul $v0, $a0, $v0 #$v0 = n * fact(n-1) jr $ra #return to caller (2nd) Kiến trúc Máy tính– Chương 3 © Fall 2017 58
- dce 2017 Giá trị trên stack khi n=2 (thời điểm 2) old TOS $sp • Stack sau khi thực thi lệnh jal lần 2 (gọi hàm fact với $a0 lúc này bằng 0) − Lưu địa chỉ trở về bk_f (vị trí sau lệnh jal) vào stack − Lưu giá trị $a0 trước đó (n=1) vào stack $ra $a0 $v0 Kiến trúc Máy tính– Chương 3 © Fall 2017 60
- dce 2017 Giá trị trên stack khi n=2 (thời điểm 4) old TOS $sp • Stack khi thực thi lệnh jr vị trí thứ 2 (trở về sau khi gán $v0 = 1 * 1) − trở về vị trí $ra = bk_f được phục hồi từ stack − giá trị $a0 = 2 cũng được phục hồi từ stack − phục hồi stack pointer $ra $a0 $v0 Kiến trúc Máy tính– Chương 3 © Fall 2017 62