Mục đích thực tế và việc sử dụng thanh ghi EDI & ESI trong trình hợp dịch là gì?
Tôi biết chúng được sử dụng cho các hoạt động chuỗi cho một thứ.
Ai đó cũng có thể cho một ví dụ?
Mục đích thực tế và việc sử dụng thanh ghi EDI & ESI trong trình hợp dịch là gì?
Tôi biết chúng được sử dụng cho các hoạt động chuỗi cho một thứ.
Ai đó cũng có thể cho một ví dụ?
Câu trả lời:
Có một số thao tác bạn chỉ có thể thực hiện với DI / SI (hoặc các bản sao mở rộng của chúng, nếu bạn không học ASM vào năm 1985). Trong số này có
REP STOSB
REP MOVSB
REP SCASB
Tương ứng, đó là các hoạt động lưu trữ, tải và quét lặp lại (= hàng loạt). Những gì bạn làm là bạn thiết lập SI và / hoặc DI để trỏ vào một hoặc cả hai toán hạng, có lẽ đặt một số đếm trong CX và sau đó để 'er rip. Đây là những hoạt động hoạt động trên nhiều byte cùng một lúc và chúng đặt CPU ở trạng thái tự động. Bởi vì bạn không mã hóa các vòng lặp một cách rõ ràng, chúng thực hiện công việc của mình hiệu quả hơn (thường là) so với một vòng lặp được mã hóa thủ công.
Đề phòng trường hợp bạn đang thắc mắc: Tùy thuộc vào cách bạn thiết lập hoạt động, việc lưu trữ lặp đi lặp lại có thể đơn giản như đục giá trị 0 vào một khối bộ nhớ lớn liền kề; Tôi nghĩ MOVSB được sử dụng để sao chép dữ liệu từ một bộ đệm (tốt, bất kỳ loạt byte nào) sang một bộ đệm khác; và SCASB được sử dụng để tìm kiếm một byte phù hợp với một số tiêu chí tìm kiếm (Tôi không chắc liệu nó chỉ tìm kiếm trên bình đẳng hay sao - bạn có thể tra cứu nó :))
Đó là hầu hết những gì những regs là cho.
SI
= Chỉ mục nguồn
DI
= Chỉ mục đích
Như những người khác đã chỉ ra, chúng có những công dụng đặc biệt với các hướng dẫn chuỗi. Để lập trình chế độ thực, ES
thanh ghi phân đoạn phải được sử dụng với DI
và DS
với SI
như trong
movsb es:di, ds:si
SI và DI cũng có thể được sử dụng làm thanh ghi chỉ mục mục đích chung. Ví dụ, C
mã nguồn
srcp [srcidx++] = argv [j];
biên dịch thành
8B550C mov edx,[ebp+0C]
8B0C9A mov ecx,[edx+4*ebx]
894CBDAC mov [ebp+4*edi-54],ecx
47 inc edi
nơi ebp+12
chứa argv
, ebx
đang j
, và edi
có srcidx
. Lưu ý rằng lệnh thứ ba sử dụng đa điểm edi
bởi 4 và thêm ebp
bù đắp bởi 0x54 (vị trí củasrcp
); dấu ngoặc xung quanh địa chỉ cho biết hướng.
AX
= bộ tích lũy
DX
= bộ tích lũy từ kép
CX
= bộ đếm
BX
= thanh ghi cơ sở
Chúng trông giống như các thanh ghi mục đích chung, nhưng có một số hướng dẫn (bất ngờ?) Sử dụng một trong số chúng — nhưng cái nào? - một cách rõ ràng.
Các mã quang học như MOVSB và MOVSW sao chép hiệu quả dữ liệu từ bộ nhớ được ESI trỏ tới vào bộ nhớ được chỉ ra bởi EDI. Vì vậy,
mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!
Ngoài các hoạt động chuỗi (MOVS / INS / STOS / CMPS / SCASB / W / D / Q, v.v.) được đề cập trong các câu trả lời khác, tôi muốn thêm rằng cũng có nhiều hướng dẫn lắp ráp x86 "hiện đại" hơn sử dụng ngầm tại EDI / RDI ít nhất:
Lệnh SSE2 MASKMOVDQU
(và sắp tới là AVX VMASKMOVDQU
) ghi các byte một cách chọn lọc từ thanh ghi XMM vào bộ nhớ được EDI / RDI trỏ tới.
Ngoài các thanh ghi được sử dụng cho các hoạt động hàng loạt, chúng hữu ích cho thuộc tính được bảo toàn thông qua một lệnh gọi hàm (cuộc gọi được bảo toàn) trong quy ước gọi 32-bit. ESI, EDI, EBX, EBP, ESP được bảo toàn cuộc gọi trong khi EAX, ECX và EDX không được bảo toàn cuộc gọi. Các thanh ghi được bảo toàn lời gọi được hàm thư viện C tôn trọng và giá trị của chúng vẫn tồn tại thông qua các lệnh gọi hàm thư viện C.
Jeff Duntemann trong cuốn sách hợp ngữ của mình có một mã hợp ngữ ví dụ để in các đối số dòng lệnh. Mã sử dụng esi và edi để lưu trữ bộ đếm vì chúng sẽ không thay đổi bởi hàm thư viện C printf. Đối với các thanh ghi khác như eax, ecx, edx, không có gì đảm bảo rằng chúng không được sử dụng bởi các hàm thư viện C.
https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025
Xem phần 12.8 Cách C xem Đối số dòng lệnh.
Lưu ý rằng quy ước gọi 64-bit khác với quy ước gọi 32-bit và tôi không chắc liệu các thanh ghi này có được bảo toàn lệnh gọi hay không.