2011-09-28 122 views
5

Tôi đang sử dụng một cái gì đó như SPIMS hoặc MARS với hàm syscall.Truy cập một ký tự trong một chuỗi

Tôi đọc trong một chuỗi (và nó hoạt động vì tôi có thể in nó ra) như sau:

li $v0, 8 
la $a0, string 
li $a1, 256 
syscall 

Tuy nhiên, tôi đang gặp một vấn đề truy cập vào một nhân vật duy nhất của chuỗi. Vì vậy, nếu tôi muốn truy cập các ký tự đầu tiên và in nó, tôi đang cố gắng này:

la $t0, string 
lb $a0, ($t0) 
li $v0, 4 
sys call 

Nếu tôi cố gắng một cái gì đó như thế này:

la $a0, string 
li $v0, 4 
syscall 

này in ra toàn bộ chuỗi như điểm chuỗi các toàn bộ chuỗi.

Nếu tôi cố gắng một cái gì đó như:

la $a0, string 
lb $a0, ($t0) 
li $v0, 4 
syscall 

Nó mang lại cho tôi một trong số lỗi ràng buộc. Tôi không hiểu tại sao mặc dù - không phải là một nhân vật một byte dài và điều này chỉ tải byte đầu tiên từ chuỗi thành $ a0?

Cảm ơn bạn

Trả lời

10

Nhìn vào documentation cho các chức năng syscall MARS bạn có thể thấy rằng dịch vụ 4, mà bạn đang sử dụng, hy vọng $a0 là "[các] địa chỉ của chuỗi null-chấm dứt để in", giải thích hành vi bạn đang thấy.

Những gì bạn muốn có chức năng 11 "ký tự in", in byte thứ tự thấp dưới dạng ký tự. Nói cách khác, những điều sau đây sẽ hoạt động (không được kiểm tra):

la $t0, string 
lb $a0, ($t0) 
li $v0, 11 
syscall 
+3

IMO bạn nên luôn đặt lại giá trị đăng ký trước khi thực hiện LI. Bạn không bao giờ biết những gì nửa trên có thể có. – m0skit0

+4

'LI' là một pseudo-op mà assembly thường mở rộng thành' ORI $ rd, $ zero, low16bits', tiếp theo là 'LUI $ rd, hi16bits'. 32 bit đầy đủ của thanh ghi đích được đặt chính xác sau lệnh 'LI', vì vậy không cần thiết phải đặt lại thanh ghi trước khi một' LI'. – markgz

+0

Bạn chắc chắn đúng – m0skit0