volatile
hay không, chỉ kỹ thuật lý do tại sao EAX
sẽ đã được khởi tạo trực tiếp trước khi thực hiện cuộc gọi chức năng trên Windows là nếu đó function
được khai báo __syscall
, tức là sử dụng các quy ước gọi của Windows CS_SYSCALL. Về mặt khái niệm, điều này hơi giống với quy ước của UN * X x86_64, trong đó %al
chứa số lượng các loại dấu phẩy động được chuyển qua trong thanh ghi %xmm
.
Quy ước gọi điện trên syscall trên Windows giống hệt với __cdecl
, tức là hàm args trên stack theo thứ tự ngược lại, nhưng với phần bổ sung AL
chứa số lượng đối số; điều này được thực hiện sao cho mã hạt nhân thường ở đầu cuối cùng của điều này biết có bao nhiêu dữ liệu để đọc từ ngăn xếp người dùng lên ngăn xếp hạt nhân để truy lục args.
EAX
là đăng ký đầu cho tất cả các quy ước gọi trên Windows 32 bit, giá trị của nó không bao giờ được bảo toàn qua cuộc gọi hàm, khởi chạy trực tiếp trước khi thực hiện cuộc gọi. Ngay cả khi biến nó giữ là volatile
- bởi vì tải lại đơn giản không phải là một rào cản bộ nhớ và không "cam kết" một cửa hàng trước đó. Ngoài ra, vị trí [EBP - 4]
nằm trong ngăn xếp , do đó, biến là địa phương (và bộ định tính volatile
không có ý nghĩa gì).
Nếu nó không phải là một tối ưu hóa nhỡ sau đó nó có thể là một lời kêu cầu của một __syscall function(...)
với số lượng khác nhau của các đối số, như, giả thuyết,
__syscall printf_syscall_conv(char *fmt, ...);
void possibly_print_three_vals(char *fmt, int val1, int val2, int val3)
{
if (*strchr('%', fmt) == '\0') // if no "%" in fmt, pass no args
printf_syscall_conv(fmt);
else
printf_syscall_conv(fmt, val1, val2, val3);
}
này hình dung có thể tạo ra sản lượng lắp ráp như của bạn.
Nguồn
2012-01-25 12:56:28
Tôi đã nhìn thấy trình biên dịch thực hiện những điều dumber hơn ... – Mysticial
@Micicial: Oh lol ... đây là lần đầu tiên tôi nhận thấy một cái gì đó như thế này. :) Tốt để biết. – Mehrdad
Có lẽ có một nhánh vào lần đẩy đầu tiên. –