2017-10-15 19 views
6

Tôi có một số mã lắp ráp gnu cho kiến ​​trúc x86_64 được tạo ra bởi một công cụ và có những hướng dẫn sau:Lệnh callq là gì?

movq %rsp, %rbp 
leaq str(%rip), %rdi 
callq puts 
movl $0, %eax 

tôi không thể tìm thấy tài liệu thực tế trên hướng dẫn "callq".

Tôi đã xem http://support.amd.com/TechDocs/24594.pdf là "Hướng dẫn sử dụng trình lập trình 3 của AMD64: Hướng dẫn chung và hướng dẫn hệ thống" nhưng chúng chỉ mô tả CALL hướng dẫn gần và xa.

Tôi đã xem tài liệu về trình kết hợp gnu https://sourceware.org/binutils/docs/as/index.html nhưng không thể tìm thấy phần chi tiết hướng dẫn mà bộ phận hỗ trợ.

Tôi hiểu rằng đó là lời gọi hàm, nhưng tôi muốn biết chi tiết. Tôi có thể tìm thấy chúng ở đâu?

+0

Tôi rất tò mò, @Peter, tại sao bạn thường đăng câu trả lời dưới dạng nhận xét thay vì câu trả lời. – prl

+1

@prl: Tôi làm điều đó khi tôi nghĩ rằng chúng có thể trùng lặp, nhưng tôi không dành thời gian để tìm một mục tiêu lừa đảo. Tôi sẽ tìm cái này; nếu nó không phải là một bản sao nó là giá trị bằng văn bản một câu trả lời thực sự. Và bạn nói đúng, tôi có thể vừa mới đăng câu trả lời đó. –

+2

@prl: Tôi không tìm thấy bất kỳ câu hỏi nào về 'callq' cụ thể. Và có thực sự là không rõ ràng công cụ để nói về mặc định operand-kích cỡ cho các chi nhánh và hướng dẫn ngăn xếp khác. Đây là một câu hỏi mới, nhưng thực sự là một câu hỏi đáng trả lời cho một sự thay đổi, nếu tôi ngừng gắt gỏng với tất cả các câu hỏi "mã của tôi không hoạt động và tôi không biết bất cứ điều gì". –

Trả lời

7

Chỉ là call. Sử dụng tháo gỡ cú pháp Intel nếu bạn muốn có thể tra cứu các hướng dẫn trong sách hướng dẫn sử dụng Intel/AMD.

Hậu tố kích thước toán hạng q áp dụng về mặt kỹ thuật (nó đẩy địa chỉ trả về 64 bit và xử lý RIP dưới dạng đăng ký 64 bit), nhưng không có cách nào ghi đè nó bằng tiền tố hướng dẫn. tức là calllcallw không được mã hóa ở chế độ 64 bit, do đó, nó chỉ gây phiền nhiễu khi một số công cụ cú pháp AT & T hiển thị nó là callq thay vì call. Tất nhiên, điều này cũng áp dụng cho retq.

Các công cụ khác nhau ở chế độ 32 so với chế độ 64 bit. (Godbolt)

  • gcc -S: luôn luôn call/ret. Tốt đẹp.
  • clang -S: callq/retqcalll/retl. Ít nhất nó luôn gây phiền nhiễu.
  • objdump -d: callq/retq (rõ ràng 64-bit) và call/ret (ẩn trong 32 bit). Không phù hợp và kinda câm vì 64-bit không có sự lựa chọn của operand-size, nhưng 32-bit nào. (Không phải là một hữu ích lựa chọn, mặc dù:. callw truncates EIP đến 16 bit)

    Mặc dù mặt khác, kích thước mặc định toán hạng (không có tiền tố REX.W) cho nhất hướng dẫn trong chế độ 64-bit vẫn còn 32. Nhưng add $1, (%rdi) cần hậu tố kích thước toán hạng; người lắp ráp sẽ không chọn 32-bit cho bạn nếu không có gì ngụ ý. OTOH, push hoàn toàn là pushq, mặc dù pushw $1pushq $1 đều được mã hóa (and usable in practice) ở chế độ 64 bit.


Từ thủ của Intel hướng dẫn thiết lập ref (liên kết ở trên):

Đối với một cuộc gọi gần tuyệt đối, một tuyệt đối bù đắp được quy định gián tiếp trong một thanh ghi mục đích chung hoặc một vị trí bộ nhớ (r/m16, r/m32, hoặc r/m64). Thuộc tính kích thước toán hạng xác định kích thước của toán hạng đích (16, 32 hoặc 64 bit).Khi ở chế độ 64 bit, kích thước toán hạng cho cuộc gọi gần (và tất cả các nhánh gần) bị buộc phải 64 bit.

cho rel32 ... Như với bù trừ tuyệt đối, thuộc tính kích thước toán hạng xác định kích thước của toán hạng đích (16, 32 hoặc 64 bit). Trong chế độ 64 bit, toán hạng đích sẽ luôn là 64 bit vì kích thước toán hạng được buộc phải 64 bit cho các nhánh gần.

Trong chế độ 32-bit, bạn có thể mã hóa 16-bit call rel16 rằng truncates EIP đến 16 bit, hoặc một call r/m16 có sử dụng một địa chỉ 16-bit tuyệt đối. Nhưng như hướng dẫn sử dụng cho biết, kích thước toán hạng được cố định ở chế độ 64-bit.

+1

Tôi thích biểu mẫu "liên tục gây phiền nhiễu".

Các vấn đề liên quan