2008-11-20 40 views
6

Tôi nhận thấy rằng trình biên dịch là rất cụ thể, nhưng kỳ vọng của tôi là vị trí của trình định danh xa nên có ý nghĩa đối với những người thực sự hiểu các con trỏ.Sử dụng các con trỏ chức năng xa

Vì vậy, tôi có hai ứng dụng chia sẻ toàn bộ không gian bộ nhớ của bộ xử lý.

App A có nhu cầu gọi hàm foo tồn tại trong ứng dụng B.

tôi biết vị trí bộ nhớ của hàm foo.

Vì vậy, điều này sẽ làm việc, trong ứng dụng A:

typedef int (* __far MYFP)(int input); 

void somefunc(void) 
{ 
    int returnvalue; 
    MYFP foo; 

    foo = (MYFP) 0xFFFFFA; 

    returnvalue = foo(39); 
} 
  • Là __far ở vị trí đúng trong typedef?
  • Tôi có cần thêm __far vào tập tin (MYFP) không?
  • Một số thông tin cho thấy rằng lệnh gọi tới foo không cần phải bị hủy đăng ký, trải nghiệm của bạn là gì?
  • Điều gì khác về vấn đề này có vẻ không chính xác hoặc tôi có thể thử thực hiện việc này không?

  • Có cách nào tốt hơn để thực hiện việc này không?

Edit:

Đây là trên một thiết bị nhúng (Freescale S12XEQ thiết bị) sử dụng Mã Warrior. Đó là một thiết bị 16 bit với không gian bộ nhớ 24 bit, do đó, có, nó được phân đoạn/ngân hàng.

-Adam

+0

Bạn có thể cung cấp thêm thông tin? Bạn đang sử dụng nền tảng nào? Bạn đang sử dụng trình biên dịch nào? – grieve

Trả lời

8

__far có đúng vị trí trong typedef không?

[Chỉnh sửa, để phản ứng lại lời nhận xét của ChrisN - nhờ]

Đây là một tính năng biên dịch phụ thuộc, vì nó không phải là một phần của ANSI C. Theo hướng dẫn biên dịch < http://www.freescale.com/files/soft_dev_tools/doc/ref_manual/CW_Compiler_HC12_RM.pdf >, chương 8 , bạn đã đặt nó đúng cách. Trong các trình biên dịch khác, bạn có thể cần phải đảo ngược thứ tự. Điều này nên được khá dễ dàng để tìm ra, mặc dù, vì chính xác một trong hai lựa chọn sẽ biên dịch với bất kỳ trình biên dịch nhất định.

Tôi có cần thêm __far vào (MYFP) truyền không?

Không, đó là một phần của loại.

Một số thông tin cho thấy rằng lệnh gọi tới foo không cần phải bị hủy đăng ký, trải nghiệm của bạn là gì?

con trỏ hàm có thể được tùy dereferenced trong C. Các dòng sau đều hợp lệ làm điều tương tự chính xác:

foo = (MYFP)0xFFFFFA; 
returnvalue = foo(39); // 1 
returnvalue = (*foo)(39); // 2 

gì nữa về điều này có vẻ không chính xác, hoặc tôi có thể cố gắng thực hiện điều này?

Bạn đã hoàn thành chính xác.

+1

Câu trả lời hay, ngoại trừ tài liệu cho trình biên dịch mà anh ta sử dụng nói rằng cú pháp con trỏ hàm phải được gõ int (* __far MYFP) (int). Xem http://www.freescale.com/files/soft_dev_tools/doc/ref_manual/CW_Compiler_HC12_RM.pdf – ChrisN

10

Từ khóa __far, ít nhất là trong thế giới MS, được sử dụng khi tạo mã nhị phân mà sử dụng bộ nhớ phân đoạn. Bạn cần hiểu hệ thống bộ nhớ 8086 để hiểu điều này. 8086 chia bộ nhớ thành các phân đoạn, mỗi đoạn dài 64K, vì vậy mỗi địa chỉ trong một đoạn cần 16bits. Địa chỉ có hai dạng: gần và xa. Một địa chỉ gần là 16bits và là một bù đắp vào phân đoạn hiện tại, một trong CS, DS, ES, SS tùy thuộc vào hướng dẫn, một xa là 32bits và bao gồm một phân đoạn và một bù đắp. Trong 8086, địa chỉ tuyệt đối là 16 * segment + offset, cho dải địa chỉ 1Mb.

Nếu bạn không sử dụng hệ thống bộ nhớ được phân đoạn và có vẻ như bạn không có, thì tất cả các địa chỉ đều có cùng số bit nên sự khác biệt gần/xa là không cần thiết, có nghĩa là từ khóa có thể bị bỏ qua bởi trình biên dịch.

+0

Vâng, nó có nghĩa là đã có 4096 cách để giải quyết cùng một byte bộ nhớ. – Skizz

+0

__far không chỉ tồn tại trên gia đình x86 với phân đoạn địa chỉ. M68k, PowerPC và một số khác cũng có vòng loại này. Tôi nghĩ rằng trong nhúng nó vẫn được sử dụng. Để trả lời câu hỏi ban đầu, chúng tôi cần thêm thông tin (như plattform, compiler, ...) – flolo

+0

Tôi hiểu điều này, và có, bộ nhớ của tôi được phân đoạn. –

1

Đây là đoạn mã hoạt động từ dự án tôi đang làm việc. Đó là Paradigm C++, vì vậy nó sử dụng một số phiên bản của Borland. CPU nó sử dụng là một bản sao 8086, do đó, bộ nhớ 20-bit phân đoạn.

void softSerial0SR(unsigned16); 
void (__far *softHandler)(unsigned16); 

Tôi khởi tạo softHandler thành 0 mà không cần khiếu nại.

Sau đó,

softHandler = softSerial0SR; 

trong mã thiết lập.

Để gọi nó, chỉ cần gọi softHandler như một chức năng thông thường.

Lưu ý rằng mã này hơi được điều chỉnh cho bạn từ mã thực mà tôi có.

0

cả hai chương trình đều được xây dựng bởi cùng một trình biên dịch/tùy chọn, vì vậy chúng sử dụng cùng một OBI?

0

Đồng ý mã có vẻ ổn - trong trường hợp này, tôi sẽ nhận được mã tháo gỡ mã được tạo và tìm hiểu xem mã có xuất hiện đúng không. Chỉ nên có 10 hướng dẫn nhiều nhất - và sau đó bạn sẽ biết chắc chắn liệu nó có hoạt động hay không.

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