Nếu báo cáo, và tất cả các báo cáo kiểm soát dòng chảy khác, là thực hiện ở cấp độ logic như nhảy có điều kiện.
Khi bạn sử dụng một câu lệnh if, như thế này:
int a = 1, b = 0
if (a > b)
{
...
Rõ ràng, bất kỳ trình biên dịch thông minh sẽ tối ưu hóa này ra. Nếu chúng ta hướng dẫn cụ thể trình biên dịch của chúng tôi để được như câm càng tốt và tạo ra các hướng dẫn đúng nguyên văn, chúng tôi sẽ nhận được một cái gì đó như sau ra khỏi nó:
my_if_statement:
CMP eax, ebx # intrinsically works by subtracting ebx from eax
# eax and ebx are not changed, but the arithmetic flags are
# if it was greater, jump to greater label
JG my_if_statement_was_true
# if it wasn't greater, we get here
my_if_statement_was_false:
# do something
# we're now done, so jump to the end of the statement
J my_if_statement_end
my_if_statement_was_true:
# do something else
# now we're done with the if statement
my_if_statement_end:
# program continues
Đây là lắp ráp hướng dẫn, mỗi trong số đó dịch (khoảng) trực tiếp đến mã máy mã opcodes. Bộ vi xử lý thực hiện một loạt các công cụ bổ sung để hỗ trợ quá trình tải và tìm nạp hướng dẫn, có liên quan ở đây. Có một thanh ghi đặc biệt được gọi là bộ đếm chương trình (được gọi là đăng ký PC), theo dõi vị trí của mã opcode tiếp theo mà bộ vi xử lý sẽ thực hiện.
- Đầu tiên, lệnh CMP trừ toán hạng thứ hai khỏi toán hạng nhất và loại bỏ kết quả. Tuy nhiên, thanh ghi FLAGS được cập nhật với kết quả của phép toán số học.
- Sau đó, lệnh JG sẽ kiểm tra xem cờ GREATER trong thanh ghi FLAGS có được đặt hay không. Vì nó nằm trong ví dụ của chúng ta (gọi lại là 1> 0), nó thực hiện một bước nhảy.
- Lệnh nhảy sửa đổi bộ đếm chương trình (PC), là thanh ghi điều khiển nơi CPU sẽ đọc lệnh tiếp theo từ đó.
- CPU sau đó cố gắng đọc hướng dẫn tiếp theo. Vì chúng ta đã nhảy, lệnh tiếp theo không phải là lệnh ngay lập tức theo lệnh được xử lý trước đó.
Đó là tổng quan về quy trình. Nếu bạn muốn giải thích sâu hơn, tôi khuyên bạn nên viết một chương trình C đơn giản với câu lệnh if, biên dịch nó, tháo rời nó (sử dụng linux objdump
hoặc tương đương), và có thể đính kèm một trình gỡ rối vào nó và chạy nó.
linux objdump
manual
Để hiển thị các lệnh kế tiếp để được thực thi trong gdb
, sử dụng display/i $pc
Câu hỏi hay! câu trả lời phức tạp mặc dù. Bạn cần phải nhìn thấy nó xảy ra để hiểu nó hoàn toàn, tôi khuyên bạn nên viết một ví dụ đơn giản, biên dịch nó, gắn nó với một trình gỡ rối, và bước qua nó, một hướng dẫn tại một thời điểm. – Wug
@wug thats một ý tưởng tuyệt vời, cảm ơn. – Nealon