2010-07-30 13 views
8

tôi đang học asm trên Linux (noobuntu 10,04) Tôi có đoạn mã sau tắt của: http://asm.sourceforge.net/intro/hello.htmlhội, chào hỏi thế giới

section .text 
global _start ;must be declared for linker (ld) 

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

Đó là một hello world đơn giản. Chạy trên Linux + gọi trực tiếp hạt nhân (rõ ràng). Có ai vui lòng giải thích điều gì đang thực sự xảy ra ở đây không? Tôi nghĩ rằng nó đọc các số nguyên trong bộ vi xử lý eax & ebx đăng ký & ecx, dữ liệu edx và xác định cuộc gọi hệ thống khi hạt nhân được gọi. Nếu vậy, các kết hợp khác nhau của các số nguyên có xác định các cuộc gọi hệ thống khác nhau khi int 0x80 được gọi không?

Tôi không tốt với các trang của người đàn ông, nhưng đã đọc mọi trang liên quan tôi có thể tìm thấy, có trang nào cho tôi biết kết hợp nào xác định những gì syscalls?

BẤT CỨ trợ giúp được đánh giá cao. Một lời giải thích từng dòng sẽ là tuyệt vời ... -Cảm ơn trước Jeremy

Trả lời

7

Khi bạn gọi int 0x80, hạt nhân nhìn vào giá trị của eax đăng ký để xác định các chức năng mà bạn muốn gọi (đây là " số syscall "). Tùy thuộc vào số đó, phần còn lại của thanh ghi được hiểu là có nghĩa là những thứ cụ thể. Cuộc gọi sys_write hy vọng ghi được thiết lập như sau:

  • eax chứa 4
  • ebx chứa các mô tả tập tin
  • ecx chứa địa chỉ của dữ liệu để viết
  • edx chứa số byte

Để biết thêm thông tin chi tiết, hãy xem Linux System Calls.

+0

Cảm ơn bạn rất nhiều, đây là sự nghi ngờ và hữu ích của tôi ... Bạn có thể cho tôi biết nơi tôi có thể tìm hiểu thêm không? Các số nguyên syscall này có nằm trong các trang của người đàn ông không? – Jeremy

+0

Bạn phải đào sâu vào các tệp tiêu đề nguồn của Linux để tìm các số gọi của hệ thống. Tôi không có một máy Linux tiện dụng vào lúc này vì vậy tôi không thể cho bạn biết vị trí chính xác, nhưng nó giống như 'include/asm/syscall.h' trong cây nguồn hạt nhân. –

+0

cảm ơn bạn rất nhiều, bạn đã được v. Hữu ích. – Jeremy

0

Có quá nhiều cuộc gọi hệ thống để có một hướng dẫn ngôn ngữ lắp ráp khác nhau cho mỗi người.

Thay vào đó, bạn gọi lệnh TRAP. Giá trị của eax xác định cuộc gọi hệ thống nào sẽ được gọi. Các thanh ghi khác là các đối số cho cuộc gọi hệ thống.

Cuộc gọi hệ thống được liệt kê bên trong hạt nhân.

+0

Cảm ơn bạn. Ở đâu, chính xác, tôi có nhìn vào các cuộc gọi hệ thống trong hạt nhân không? – Jeremy

2
section .text 
global _start ;must be declared for linker (ld) 

Đây chỉ là phần đầu trang, phần "văn bản" của chương trình lắp ráp chỉ là hướng dẫn của máy (so với dữ liệu, dữ liệu chỉ đọc và phần BSS). Dòng global tương tự như khi nói rằng hàm _start là "công khai".

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

Từ những ý kiến ​​chúng tôi biết rằng chúng tôi đang xem xét sys_write chức năng, vì vậy chúng tôi có thể man 2 write để có được những thông tin chi tiết. Nguyên mẫu C cung cấp các thông số sau: fd, *bufcount. Bắt đầu với% ebx, chúng ta thấy rằng các kết quả phù hợp đó (% ebx = fd,% ecx = chuỗi để viết và% edx = độ dài của chuỗi). Sau đó, vì chúng ta là một tiến trình người dùng, chúng ta phải yêu cầu hạt nhân thực hiện đầu ra. Điều này được thực hiện thông qua giao diện SYSCALL, và hàm write() là (rõ ràng) được đưa ra số 4. INT 0x80 là một phần mềm gián đoạn gọi là thường trình SYSCALL của hạt nhân Linux.

Bạn có thể tìm số thực tế của tất cả các syscalls trong các tệp tiêu đề Linux (giả sử bạn đã cài đặt chúng). Trên hệ thống của tôi, tôi đã kiểm tra /usr/include/sys/syscall.h dẫn đến /usr/include/asm/unistd.h và sau đó vào /usr/include/asm-i386/unistd.h. Ở đâu (tôi thấy), #define __NR_write 4.

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

Như với hai dòng cuối của phân đoạn trước, điều này chỉ tải id syscall và phần mềm ngắt để thoát chương trình (xóa bản đồ bộ nhớ và dọn dẹp).

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

Đây là phần dữ liệu, nó chỉ mô tả các biến chúng tôi đã sử dụng trong chương trình của mình.

+0

câu trả lời hữu ích nhất được nêu ra. cảm ơn bạn rất nhiều vì đã dành thời gian. – Jeremy