2013-07-13 44 views
15

Tôi rất mới để lắp ráp, và tôi không hiểu những gì nó chính xác có nghĩa là khi, ở phần cuối của một proc, bạn viết một số với tuyên bố ret.Ý nghĩa của RET trong lắp ráp

Như thế này:

Function Proc 
push ax cx 
. 
...body... 
. 
pop cx ax 
ret 2 
Function endp 

Tôi hiểu nó có cái gì để làm với nơi con trỏ stack nên quay trở lại vào cuối của hàm?

Xin vui lòng, nó thực sự sẽ giúp tôi nếu bạn có thể giải thích nó một cách dễ dàng.

+6

Hội không phải là một ngôn ngữ - mọi bộ xử lý đều có ngôn ngữ riêng. Bạn nên hỏi về một kiến ​​trúc cụ thể (có vẻ như x86). – ugoren

+0

Và câu trả lời, cho x86, là [ở đây] (http://download.intel.com/products/processor/manual/325383.pdf) – ugoren

+2

Tắt chủ đề: 'ret' là một hướng dẫn nhỏ mạnh mẽ từ lâu đã được trung tâm khai thác phần mềm lỗi: Nó chỉ đạo luồng điều khiển của chương trình theo nội dung của bộ nhớ của ngăn xếp cuộc gọi. Nếu bạn kiểm soát bộ nhớ ('strcpy', tôi đang nhìn bạn), bạn kiểm soát luồng thực hiện chương trình. –

Trả lời

14

Có, nhưng ret 2 cũng xóa 2 byte thông số khỏi ngăn xếp. Có lẽ, chức năng của bạn được gọi như:

push some_parameter 
call Function 

Tại thời điểm này, một chức năng cdecl - một "người gọi dọn dẹp" chức năng (Nói chung sử dụng bởi C) - sẽ đòi hỏi add sp, 2 để "dọn dẹp đống", loại bỏ các tham số. Một hàm như vậy sẽ kết thúc bằng một số ret đơn giản.

Chức năng stdcall, đó là những gì bạn có, là chức năng "làm sạch callee" (được sử dụng bởi API Windows) không yêu cầu add sp, 2 - nó đã được thực hiện bởi ret 2.

Nếu bạn không biết về nó, call đặt địa chỉ trả lại trên ngăn xếp (và ret bật tắt), vì vậy bạn không thể chỉ pop để lấy thông số bên trong hàm của mình.

3

Điều này có nghĩa là RETurn, như là return ở các ngôn ngữ cấp cao.

Trên hầu hết các máy, nó sẽ bật giá trị trước của bộ đếm chương trình trước khi vào chương trình con khỏi ngăn xếp và sao chép nó vào thanh ghi của máy tính.

Đối với x86, đối số là số tham số trên ngăn xếp. Điều này chỉ áp dụng nếu quy ước được sử dụng là để chương trình con xử lý việc đặt lại ngăn xếp.

+0

vậy ý ​​nghĩa của con số bên cạnh nó là gì? –

+0

@RotemMayo Hãy tham khảo bản chỉnh sửa của tôi. – alex

+2

Chỉnh sửa nhỏ: toán hạng tức thời chỉ định số lượng thừa _bytes_ để "bật" khỏi ngăn xếp khi trở về. – Michael

6

Như Alex đã nói, điều đó có nghĩa là RETURN. Trong lắp ráp x86, khi trình biên dịch đạt đến dòng này (ở cuối chương trình con), nó sẽ xuất hiện giá trị cuối cùng từ ngăn xếp, được cho là địa chỉ trả về và gán nó cho thanh ghi IP. Bạn có thể hiểu rằng tốt hơn bằng cách viết một mã assembly đơn giản và biên dịch nó với Turbo Debugger. Có một GUI cho assembler nếu bạn mới làm quen với điều đó. Bạn có thể tìm thấy GUI here.

Khi bạn đang bật và đẩy giá trị từ và đến ngăn xếp khi bạn ở trong chương trình con, bạn nên lưu địa chỉ trả về, vì vào cuối chương trình con, bạn cần đẩy nó trở lại ngăn xếp trước return hàng.

Chúc may mắn!

12

Cho phép nói rằng tôi có quy trình thêm hai từ và để tổng số tiền trong EAX. Các từ là đối số tôi muốn chuyển đến thủ tục trên ngăn xếp. tôi.e:

push word1 
push word2 
call addtwob 

Thủ tục sẽ giống như thế:

addtwob proc 

push ebp 
mov ebp,esp 
mov eax, [ebp+6]  
add eax, [ebp+8] 
pop ebp 
ret 4 

Endp 

[ebp+6][ebp+8] địa chỉ word2word1 trên stack. ret 4 chỉ trả lại như bình thường nhưng sau đó thêm 4 vào con trỏ ngăn xếp (esp), do đó bạn không cần phải giảm bớt ngăn xếp sau khi trở về từ cuộc gọi, do đó nó làm sạch/cân bằng ngăn xếp mà không cần bật các lần đẩy trước đó.

1

Dường như bạn đang hỏi về một số gần trả về với toán hạng cho x86_64. Thuật toán được theo sau bởi phần cứng khi gần RET gặp phải bởi bộ xử lý được hiển thị trong Intel instruction set reference manual như sau;

(* Near return *) 
IF instruction = near return 
    THEN; 
    IF OperandSize = 32 
     THEN 
     IF top 4 bytes of stack not within stack limits 
      THEN #SS(0); FI; //throw protected mode exception 
     EIP ← Pop(); 
     ELSE 
     IF OperandSize = 64 
      THEN 
      IF top 8 bytes of stack not within stack limits 
       THEN #SS(0); FI; //throw protected mode exception 
      RIP ← Pop(); 
      ELSE (* OperandSize = 16 *) 
      IF top 2 bytes of stack not within stack limits 
       THEN #SS(0); FI; //throw protected mode exception 
      tempEIP ← Pop(); 
      tempEIP ← tempEIP AND 0000FFFFH; 
      IF tempEIP not within code segment limits 
       THEN #GP(0); FI; //throw protected mode exception 
      EIP ← tempEIP; 
     FI; 
    FI; 
    IF instruction has immediate operand 
     THEN (* Release parameters from stack *) 
     IF StackAddressSize = 32 
      THEN 
      ESP ← ESP + SRC; 
      ELSE 
      IF StackAddressSize = 64 
       THEN 
       RSP ← RSP + SRC; 
       ELSE (* StackAddressSize = 16 *) 
      SP ← SP + SRC; 
      FI; 
     FI; 
    FI; 
FI; 
  • Theo thuật toán này bất cứ khi nào quay trở lại gần bắt gặp, địa chỉ trả lại được kiểm tra cho dù đó là trong giới hạn SS. Đầu ngăn xếp được bật vào RIP hoặc EIP theo kích thước toán hạng nếu địa chỉ trả về hợp lệ.

  • Nếu kích thước toán hạng là 16 bit, vị trí tạm thời giữ địa chỉ trả về xuất hiện được đặt bằng giá trị 0x0000FFFF và được nạp vào EIP sau khi kiểm tra giới hạn CS.

  • Khi câu hỏi của bạn hỏi về điều gì sẽ xảy ra nếu có toán hạng tới mã lệnh lệnh RET gần. Nó phụ thuộc vào kích thước địa chỉ stack. Theo đó kích thước RSP ESP hoặc SP được tăng bởi toán hạng và sau khi tất cả các lệnh RET gần được hoàn thành thực hiện trên phần cứng.

+1

'pop cx' là một dấu hiệu khá rõ ràng rằng OP đang xem xét mã 16 bit. Đối với một số lý do mọi người hỏi rất nhiều câu hỏi Stack Overflow về mã 16-bit. Một số người trong số họ đang làm hệ điều hành đồ chơi, hầu hết trong số họ đang tham gia các khóa học đại học dạy 8086 với emu8086 vì một lý do điên rồ nào đó. –