2013-06-28 40 views
5

Tôi đang cố gắng in một số mà tôi đã lưu trữ. Tôi không chắc liệu tôi có gần hay không. Bất kỳ trợ giúp sẽ được đánh giá cao mặc dù. Đây là mã của tôi:Làm thế nào để in một số trong lắp ráp ARM?

.data 
.balign 4 
a: .word 4 

.text 
.global main 
main: 
     ldr r0, addr_of_a 
     mov r1, #8 
     str r1, [r0] 
write: 
     mov r0, #1 
     ldr r1, addr_of_a 
     mov r2, #4 
     mov r7, #4 
     swi #0 
     bx lr 

addr_of_a: .word a 

Nó biên dịch và chạy, nhưng tôi không thấy gì được in. Từ những gì tôi hiểu, tôi cần địa chỉ nơi bắt đầu in trong r1, số byte trong r2, bộ mô tả tập tin trong r0 và r7 chỉ định cuộc gọi ghi nếu nó được đặt thành # 4. Tôi chỉ đơn giản là cố gắng để lưu trữ # 8, sau đó in số được lưu trữ.

+3

Bạn cần phải chuyển đổi số thành một chuỗi (ví dụ ' 123' -> '" 123 "') trước tiên. – Michael

Trả lời

4

Chữ syscall ghi vào đối số thứ hai (r1) một con trỏ tới chuỗi bạn muốn in. Bạn đang chuyển cho nó một con trỏ tới một số nguyên. Đó là lý do tại sao nó không in bất cứ điều gì, bởi vì không có ký tự ASCII trên vùng bộ nhớ bạn đang đi đến nó.

Dưới đây bạn sẽ tìm thấy chương trình "Hello World" bằng cách viết syscall.

.text 
.global main 
main: 
     push {r7, lr} 

     mov r0, #1 
     ldr r1, =string 
     mov r2, #20 
     mov r7, #4 
     svC#0 

     pop {r7, pc} 

.data 
string: .asciz "Hello World\n" 

Nếu bạn muốn in một số, bạn có thể sử dụng chức năng printf từ thư viện C. Như thế này:

.text 
.global main 
.extern printf 
main: 
     push {ip, lr} 

     ldr r0, =string 
     mov r1, #1024 
     bl printf 

     pop {ip, pc} 

.data 
string: .asciz "The number is: %d\n" 

Cuối cùng, nếu bạn muốn in số bằng syscall thì bạn cũng có thể thực hiện hàm itoa (hàm chuyển đổi số nguyên thành chuỗi).

+1

Tôi đã tìm kiếm câu trả lời về cách chuyển đổi một số nguyên thành một char trong hội đồng ARM. Tất cả các kết quả tôi nhận được giải thích làm thế nào để làm điều đó trong C mặc dù. Làm thế nào tôi sẽ đi về việc chuyển đổi này trong ARM mà không có các thư viện C? –

+0

Hãy nhớ rằng các ký tự không là gì hơn số trong mã ASCII. Số 48 tương ứng với char '0' trong ASCII. Số 49 đến '1' và vân vân. Nếu bạn muốn chuyển đổi một số nguyên thành một char, do đó, bạn có thể thêm 48 vào số nguyên, và sau đó lưu trữ kết quả dưới dạng một byte (và không phải là số nguyên, vì ints có 4 byte) ở một số vị trí bộ nhớ. Sau đó, nếu bạn gửi một con trỏ của vị trí bộ nhớ đó đến syscall thì nó sẽ in ra ký tự. –

3

Xin chào, tôi đánh giá cao đây là một chủ đề khá cũ nhưng tôi đã gãi đầu về vấn đề này một thời gian và muốn chia sẻ giải pháp của mình. Có lẽ nó sẽ giúp ai đó trên đường đi! Tôi đang hướng đến in chữ số mà không cần sử dụng C++ theo bất kỳ cách nào, mặc dù tôi nhận ra rằng chỉ cần giải mã một chuỗi() - hoặc bất kỳ tương đương nào tồn tại trong C++ - và nhìn thấy những gì đã xảy ra tuyến đường nhanh hơn. Về cơ bản, tôi đã kết thúc bằng việc tạo một con trỏ tới một chuỗi rỗng .ascii trong phần .data và thêm chữ số mà tôi muốn in + 48 vào nó trước khi in ra chữ số đó.

+48 tất nhiên là tham chiếu đến số chỉ mục ascii của chữ số cụ thể.

.global _start 

_start: 
MOV R8, #8 
ADD R8, R8, #48 

LDR R9, =num 
STR R8, [R9] 

MOV R0, #1 
LDR R1, =num 
MOV R2, #1 
MOV R7, #4 
SWI 0 

.data 

num: 
.ascii: " " 

Hạn chế lớn nhất của phương pháp này là nó không xử lý bất kỳ số nào dài hơn một chữ số.

Giải pháp của tôi cho đó là nhiều, xấu xí hơn và vượt quá phạm vi của câu trả lời này ở đây nhưng nếu bạn đã một dạ dày mạnh mẽ, bạn có thể nhìn thấy nó here:

+0

Nhiều trình kết hợp cho phép bạn sử dụng hằng số ASCII trong các biểu thức, ví dụ: '# '0'' thay vì' # 48'. IDK nếu bộ ghép ARM cho phép điều này, nhưng nó ''0'' làm việc với bộ ghép GNU cho x86. Ngoài ra, bạn không cần '.ascii' để được khởi tạo, bởi vì bạn không đọc nó trước khi viết. –

+0

Rất vui được biết. Tôi sẽ kiểm tra điều đó, sẽ cứu tôi một chút phiền toái! – Tombas

Các vấn đề liên quan