Tôi đã xem qua một đoạn mã void *p = &&abc;
. Ý nghĩa của việc &&
này là gì? Tôi biết về tham chiếu rvalue nhưng tôi nghĩ &&
được sử dụng trong ngữ cảnh này là khác nhau. Điều gì &&
chỉ ra trong void *p = &&abc;
?
Tôi đã xem qua một đoạn mã void *p = &&abc;
. Ý nghĩa của việc &&
này là gì? Tôi biết về tham chiếu rvalue nhưng tôi nghĩ &&
được sử dụng trong ngữ cảnh này là khác nhau. Điều gì &&
chỉ ra trong void *p = &&abc;
?
Câu trả lời:
&&
là phần mở rộng của gcc để lấy địa chỉ của nhãn được xác định trong hàm hiện tại.
void *p = &&abc
là bất hợp pháp trong tiêu chuẩn C99 và C ++.
Điều này biên dịch với g ++.
void*
.
__forceinline
? __declspec(naked)
? Một trong những MSVCisms yêu thích của tôi là:, là template<typename T> class X { friend T; }
C ++ 03 không hợp lệ.
Đó là địa chỉ của một nhãn và đó là một tính năng dành riêng cho GCC .
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Bạn có thể tự mình tìm ra nó bằng cách thử nghiệm:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
Trong trường hợp đó, GCC nói:
error: nhãn 'a' được sử dụng nhưng không được xác định
Bạn cần biết trình hợp ngữ để thực sự hiểu điều này, nhưng tôi sẽ cố gắng giải thích cho bạn địa chỉ của nhãn nghĩa là gì.
Sau khi hệ điều hành tải tệp .exe từ đĩa, một thành phần của hệ điều hành được gọi là "trình tải" (windows có "PE Loader", linux có "ELF loader" hoặc thậm chí có thể khác, nếu chúng được biên dịch trong kernel), nó thực hiện "ảo hóa" chương trình đó, biến nó thành một tiến trình.
Quá trình này cho rằng nó là duy nhất trong RAM và nó có quyền truy cập vào toàn bộ RAM (nghĩa là 0x00000000-0xFFFFFFFF trên máy 32 bit).
(ở trên chỉ là bản tóm tắt ngắn về những gì đang xảy ra, bạn thực sự cần phải học lắp ráp để hiểu nó đầy đủ, vì vậy hãy chịu đựng với tôi)
Bây giờ, nhãn trong mã nguồn về cơ bản là một địa chỉ. "nhãn goto;" không làm gì khác hơn là một bước nhảy đến địa chỉ đó (hãy nghĩ về con trỏ hướng dẫn trong hợp ngữ). Nhãn này lưu trữ địa chỉ RAM này và đó là cách bạn có thể tìm ra địa chỉ đó.
Sau khi bạn đã học ASM, bạn sẽ nhận ra rằng địa chỉ đó trỏ đến một chỉ dẫn trong .text
phần của tệp thực thi. Phần .text
này là phần chứa mã (nhị phân) của chương trình của bạn sẽ được thực thi.
Bạn có thể kiểm tra điều này bằng:
objdump -x a.out
Như được mô tả trong GCC , bạn có thể sử dụng nó để khởi tạo bảng nhảy. Một số trình tạo máy quét như re2c (xem -g
thông số) sử dụng điều đó để tạo ra các máy quét nhỏ gọn hơn. Thậm chí có thể có một trình tạo phân tích cú pháp sử dụng cùng một kỹ thuật.