2016-08-28 20 views
9

Tôi là người mới bắt đầu lắp ráp (sử dụng nasm). Tôi đang học lắp ráp thông qua một khóa học đại học.Tại sao hệ thống sys_read gọi kết thúc khi phát hiện một dòng mới?

Tôi đang cố gắng hiểu hành vi của cuộc gọi hệ thống linux sys_read khi được gọi. Cụ thể, sys_read dừng khi đọc dòng mới hoặc nguồn cấp dữ liệu dòng. Theo những gì tôi đã được dạy, điều này đúng. Điều này online tutorial article cũng khẳng định thực tế/yêu cầu bồi thường.

Khi sys_read phát hiện nguồn cấp dữ liệu dòng, kiểm soát trở lại chương trình và đầu vào của người dùng được đặt tại địa chỉ bộ nhớ bạn đã chuyển trong ECX.

Tôi đã kiểm tra hướng dẫn của lập trình viên linux cho cuộc gọi sys_read (qua "man 2 read"). Nó không đề cập đến hành vi khi nó được cho là phải không?

đọc() cố gắng đọc tối đa số byte từ bộ mô tả tệp fd vào bộ đệm bắt đầu tại buf.

Trên các tệp hỗ trợ tìm kiếm, thao tác đọc bắt đầu ở mức bù đắp tệp và bù đắp tệp được tăng lên theo số byte đọc. Nếu bù đắp tập tin ở hoặc qua cuối tệp, không có byte nào là đọc và đọc() trả về 0.

Nếu đếm bằng không, hãy đọc() có thể phát hiện các lỗi được mô tả bên dưới. Trong sự vắng mặt của bất kỳ lỗi nào, hoặc nếu read() không kiểm tra lỗi, một số đọc() với tổng số 0 trả về 0 và không có hiệu ứng nào khác.

Nếu số lớn hơn SSIZE_MAX, kết quả không được chỉ định.

Vì vậy, câu hỏi của tôi thực sự là, tại sao hành vi xảy ra? Nó là một đặc điểm kỹ thuật trong hạt nhân Linux rằng điều này sẽ xảy ra hoặc là nó một hệ quả của cái gì khác?

Trả lời

8

Đó là vì bạn đang đọc từ POSIX tty in canonical mode (trong đó backspace hoạt động trước khi bạn nhấn quay lại để "gửi" dòng; tất cả được xử lý bởi trình điều khiển tty của hạt nhân). Tra cứu ngữ nghĩa POSIX tty/stty/ioctl. Nếu bạn chạy ./a.out < input.txt, bạn sẽ không thấy hành vi này.

Lưu ý rằng read() trên TTY sẽ trả về mà không có dòng mới nếu bạn nhấn control-d (chuỗi điều khiển tty EOF).

Giả sử rằng read() đọc toàn bộ dòng là ok cho một chương trình đồ chơi, nhưng không bắt đầu giả định rằng trong bất cứ điều gì mà cần phải được mạnh mẽ, ngay cả khi bạn đã kiểm tra rằng bạn đang đọc từ một TTY. Tôi quên điều xảy ra nếu người dùng dán nhiều dòng văn bản vào trình mô phỏng thiết bị đầu cuối. Có lẽ tất cả chúng đều kết thúc trong một bộ đệm read().


Xem thêm my answer on a question about small read()s leaving unread data on the terminal: nếu bạn gõ ký tự hơn trên cùng một dòng hơn so với kích thước bộ đệm read(), bạn sẽ cần thêm ít nhất một cuộc gọi hệ thống đọc hiểu rõ ràng đầu vào.


Như bạn lưu ý, các read(2) chức năng libc chỉ là một wrapper mỏng xung quanh sys_read. Câu trả lời cho câu hỏi này thực sự không liên quan gì đến ngôn ngữ lắp ráp, và cũng giống như đối với các hệ thống lập trình bằng ngôn ngữ C (hoặc bất kỳ ngôn ngữ nào khác).

Đọc thêm:

+0

Cảm ơn rất nhiều vì đã giải thích và tham khảo! – Mercado

3

Đây không phải là thuộc tính của cuộc gọi hệ thống read() mà là thuộc tính của termios, trình điều khiển thiết bị đầu cuối. Trong cấu hình mặc định, các bộ đệm sẽ lưu các ký tự đến (tức là những gì bạn nhập) cho đến khi bạn nhấn Nhập, sau đó toàn bộ dòng được gửi đến chương trình đọc từ thiết bị đầu cuối. Điều này thuận tiện để bạn có thể chỉnh sửa dòng trước khi gửi đi.

Như Peter Cordes đã nói, hành vi này không có mặt khi đọc từ các loại tệp khác (như tệp thông thường) và có thể được tắt bằng cách định cấu hình các thuật ngữ.

Hướng dẫn nói là rác, vui lòng bỏ qua nó.

+0

Tôi thích bức tranh cuối cùng: D Cảm ơn rất nhiều vì đã giải thích :) – Mercado

+0

@Mercado Thật là một niềm vui đối với tôi! – fuz

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