Mục đích của thanh ghi ESI & EDI?


119

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ụ?


9
Kiểm tra điều này: swansontec.com/sregisters.html
Jeffpowrs

Câu trả lời:


77

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.


7
Mẹo tối ưu hóa trước đây: rep stosw nhanh hơn rất nhiều so với rep stosb , vì vậy nếu sao chép hai và hai byte phù hợp với những gì bạn đang cố gắng thực hiện, thay vào đó hãy sử dụng nó trong mã lắp ráp x86 16 bit được tối ưu hóa bằng tay của bạn ...
Alexander

88

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, ESthanh ghi phân đoạn phải được sử dụng với DIDSvới SInhư 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ụ, Cmã 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+12chứa argv, ebxđang j, và edisrcidx. Lưu ý rằng lệnh thứ ba sử dụng đa điểm edibởi 4 và thêm ebpbù đắp bởi 0x54 (vị trí củasrcp ); dấu ngoặc xung quanh địa chỉ cho biết hướng.


Mặc dù tôi không thể nhớ mình đã nhìn thấy nó ở đâu, nhưng điều này xác nhận phần lớn điều nàyđiều này (trang trình bày 17) những thứ khác:

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.


37

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!

12

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.


6

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.


Tôi chưa bao giờ nghe thấy "thiêng liêng" được sử dụng để mô tả những gì mà hầu hết mọi người gọi là "dễ bay hơi" / "không bay hơi", hoặc "được lưu lại" so với "người gọi được lưu". Tôi thích "cuộc gọi được bảo toàn" / "cuộc gọi được che đậy", vì nó không ngụ ý rằng chúng thực sự được lưu ở bất kỳ đâu. Dù sao, ESI / RSI và EDI / RDI không được bảo toàn lệnh gọi trong Hệ thống x86-64 V ABI.
Peter Cordes

Ngoài ra, bạn đã quên liệt kê EBP và ESP dưới dạng cuộc gọi được bảo toàn trong các quy ước gọi 32-bit phổ biến.
Peter Cordes

1
Dù sao, đó là một điểm khá tốt. Trong mã thực tế, bạn có nhiều khả năng chọn EDI / ESI cho một cái gì đó dựa trên lý do quy ước gọi hơn là vì chúng đặc biệt cho bất kỳ hướng dẫn nào.
Peter Cordes

Tôi thích cuộc gọi được bảo toàn. Tôi đã cập nhật câu trả lời với cùng một. Cảm ơn đã xem xét.
Jay Rajput
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.