2012-02-10 29 views
23

Dòng lệnh sau đây có ý nghĩa gì:Dấu hoa thị * trước một địa chỉ có nghĩa là gì trong lắp ráp AT & T x86-64?

... 
401147: ff 24 c5 80 26 40 00 jmpq *0x402680(,%rax,8) 
... 

không dấu hoa thị ở phía trước của địa chỉ bộ nhớ có ý nghĩa gì? Ngoài ra, nó có nghĩa là gì khi phương pháp truy cập bộ nhớ bị thiếu giá trị đăng ký đầu tiên?

Thông thường, nó giống như ("% register",% rax, 8), nhưng trong trường hợp này, nó không có thanh ghi đầu tiên.

Bất kỳ mẹo nào?

+3

lol, nhưng tôi phải biết nó để tôi có thể gỡ lỗi một số mã c. và cũng cho các bài kiểm tra lớp học. – de1337ed

Trả lời

4

Đó là bước nhảy tới địa chỉ có trong bộ nhớ. Địa chỉ được lưu trữ trong bộ nhớ tại địa chỉ rax*8+0x402680, trong đó rax là giá trị rax hiện tại (khi lệnh này thực thi).

14

Bắt mọi thứ vào cú pháp Intel luôn làm cho những thứ rõ ràng hơn:

FF24C5 80264000 JMP QWORD PTR [RAX*8+402680] 
+0

ai xuống bình chọn, quan tâm giải thích tại sao? Chỉ là cú pháp chống intel là * không * một lý do ... – Necrolis

+17

Tôi đã không downvote, nhưng bạn không chính xác giải thích những gì đang xảy ra .. –

+3

@MichaelFoukarakis: khác với lặp lại nguyên văn toán bằng tiếng Anh, không có nhiều để thực sự thêm khi sử dụng cú pháp intel. – Necrolis

14

Nó AT & T lắp ráp cú pháp:

  • nguồn đến trước điểm đến
  • hậu tố mnemonic cho thấy kích thước của toán hạng (q cho quad, v.v.)
  • thanh ghi có tiền tố % và giá trị ngay lập tức với $
  • địa chỉ hiệu quả ở dạng DISP(BASE, INDEX, SCALE) (DISP + CƠ SỞ + INDEX * THANG)
  • nhảy tuyệt đối/gọi toán hạng chỉ báo bằng * (như trái ngược với chỉ IP tương đối)

Vì vậy, bạn có một số jmpq để nhảy tới địa chỉ tuyệt đối được lưu trữ trong %rax * 8 + 0x402680 và là một từ dài bốn chữ.

+0

nhưng các dấu hoa thị ở phía trước có tạo sự khác biệt không? Tôi hiểu rằng những gì bạn nói có ý nghĩa khác. Tôi đã nghĩ rằng dấu hoa thị đầu tiên sẽ lấy dữ liệu ra khỏi vị trí bộ nhớ 0x402680. Vì vậy, basicaly, nó sẽ trở thành% rax * 8 + mem [0x402680] – de1337ed

+0

Dấu sao chỉ xác định đó là một bước nhảy tuyệt đối. 'jmp' sẽ lấy dữ liệu ra khỏi vị trí bộ nhớ được chỉ định bất kể. –

17

Thực tế đây là bảng tính jmp, trong đó 0x402680 là địa chỉ của tabele và rax là chỉ mục của con trỏ 8 byte (qword).

+3

Bàn nhảy thường được sử dụng trong mã lắp ráp khi mã C hoàn thành nếu có hoặc chuyển đổi câu lệnh. Nó cho phép điều khiển được truyền trong thời gian không đổi, thay vì phải kiểm tra rất nhiều kiểm tra bình đẳng cá nhân. – Eagle

4

Như Necrolis đã viết, cú pháp của Intel làm cho nó rõ ràng hơn một chút, nhưng RTN thực sự rõ ràng hơn. Dòng

jmpq *0x402680(,%rax,8) 

sẽ được mô tả trong RTN bởi:

RIP <- M[0x402680 + (8 * RAX)] 

nơi M là bộ nhớ hệ thống.

Như vậy, chúng ta có thể viết dạng tổng quát jmpq *c(r1, r2, k), nơi c là một hằng số ngay lập tức, r1r2 là thanh ghi mục đích chung và k hoặc là 1 (mặc định), 2, 4 hoặc 8:

RIP <- M[c + r1 + (k * r2)] 
4

jmpq chỉ là một bước nhảy không có điều kiện đến địa chỉ đã cho. Chữ 'q' có nghĩa là chúng ta đang xử lý các từ tứ (dài 64 bit).

*0x402680(,%rax,8): Đây là cách viết địa chỉ trong hội đồng x 86. Bạn đúng khi nói rằng thường có một thanh ghi trước dấu phẩy đầu tiên, nhưng bạn vẫn tuân thủ các quy tắc tương tự nếu không có đăng ký nào được chỉ định.

Định dạng hoạt động theo cách này: D(reg1, reg2, scalingFactor) trong đó D là viết tắt của chuyển vị. Displacement về cơ bản chỉ là một số nguyên. reg1 là thanh ghi đầu tiên hoặc cơ sở. reg2 là thanh ghi thứ hai và scalingFactor là một trong 2, 4, 8 (thậm chí có thể là 1, nhưng tôi không chắc chắn về điều đó). Bây giờ, bạn có thể lấy địa chỉ của mình bằng cách thêm các giá trị theo cách này: Displacement + (giá trị tại reg1) + scalingFactor * (giá trị tại reg2).

Tôi không hoàn toàn chắc chắn về dấu hoa thị ở phía trước địa chỉ, nhưng tôi đoán là điều đó có nghĩa là giá trị chuyển được lưu trữ tại địa chỉ đó.

Hy vọng điều này sẽ hữu ích.

1

Minimal dụ để làm cho mọi việc rõ ràng hơn:

.data 
    # Store he address of the label in the data section. 
    symbol: .int label 
.text 
    # Jumps to label. 
    jmp *symbol 
    label: 

Nếu không có sự *, nó sẽ nhảy đến địa chỉ của symbol trong .data phần và segfault.

tôi cảm thấy cú pháp này là một chút mâu thuẫn, bởi vì đối với hầu hết các lệnh:

mov symbol, %eax 
mov label, %eax 

đã di chuyển dữ liệu tại địa chỉ symbol, và $symbol được sử dụng cho địa chỉ. Cú pháp của Intel phù hợp hơn trong thời điểm này vì nó luôn sử dụng [] để xem xét.

Tất cả * dĩ nhiên là cách ghi nhớ cho toán tử điều khiển số D *ptr.

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