كيف يمكنني تجميع الروتينية التجمع للاستخدام مع برنامج C (GNU المجمع)؟
-
03-07-2019 - |
سؤال
ولدي مجموعة من وظيفة التجمع الذي أريد، لاستخدامها في برامج C عن طريق إنشاء ملف الرأس. على سبيل المثال، إذا كان لدي asm_functions.s الذي يحدد إجراءات التجمع وasm_functions.h التي لديها ونماذج للوظائف وكذلك بعض القياسية # تعرف أنني بحاجة فعلية. هدفي هو استخدام برنامج C، ويقول test_asm.c لاستدعاء وظائف التجمع.
وasm__functions.h:
#define ASM_CONST_1 0x80
#define ASM_CONST_2 0xaf
uint8_t asm_foo( int, int, int );
وasm__functions.s:
/* dont need this: #include "asm_functions.h" */
.section .text
.type asm_foo, @function
asm__foo:
/* asm code with proper stack manipulation for C calling conventions */
ret
وtest__asm.c:
#include "asm_foo.h"
int main() {
uint8_t res = asm_foo( 1, 2, 3);
return 0;
}
في مثل هذا الوضع ما يمكن أن يكون الطريقة الصحيحة لتجميع وصلة البرنامج؟ كنت أحاول شيئا من هذا القبيل:
gas -o asm_foo.o asm_foo.s
gcc -o test_asm test_asm.c
ولكن أنا لا تزال تحصل على خطأ رابط من دول مجلس التعاون الخليجي قائلا أن بلدي التجمع روتين غير معرف. آمل أن يكون هذا المثال مفتعلة جيدة بما يكفي لشرح الوضع.
وشكرا!
وتحرير:
وهنا مقتطف من الانتاج عندما تجمع مع أمر واحد:
tja@tja-desktop:~/RIT/SP2/latest$ gcc -o test_pci pci_config.s test_pci.c
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x8): undefined reference to
PCI_FUNCTION_ID'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0xa): undefined reference to
READ_CONFIG_BYTE'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x18): undefined reference to
PCI_BIOS_FUNCTION_INT'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x1b): undefined reference to
BAD_REGISTER_NUMBER'
/tmp/ccY0SmMN.o: In function _pci_bios_read_word':
(.text+0x30): undefined reference to
PCI_FUNCTION_ID'
...
وجميع تلك، مثل PCI_FUNCTION_ID، تم تعريفها في ملف الرأس بلدي، والتي يتم تضمينها بواسطة برنامج C. عندما تجميع رمز التجميع في حد ذاته هناك أية أخطاء.
المحلول
واستنادا إلى الملفات في سؤالك، تمكنت من ترجمة عليه. لقد تغيرت كل من أسماء الملفات ومحتويات الملف.
وasm_const.h:
#define ASM_CONST_1 0x80
#define ASM_CONST_2 0xaf
وasm_functions.h:
#include "asm_const.h"
unsigned char asm_foo( int, int, int );
وasm_functions.S (زائدة S يجب أن تكون عاصمة # تشمل يحتاج إليها!):
#include "asm_const.h"
.section .text
.globl asm_foo
.type asm_foo, @function
asm_foo:
mov $ASM_CONST_1, %eax
/* asm code with proper stack manipulation for C calling conventions */
ret
وtest_asm.c:
#include "asm_functions.h"
int main() {
return asm_foo( 1, 2, 3);
}
يرجى ملاحظة أنك بحاجة إلى ملحق الملف التجمع .S برأسمال S. مع .S، لن تشغيل ملف .S من خلال المعالج، وبالتالي سوف تتضمن # لا تعمل، وأنت لن تكون قادرة على استخدام ASM_CONST_1 في ملف .S.
وتجميع مع أمر واحد:
gcc -o test_asm asm_functions.S test_asm.c
وأو، كبديل، ترجمة مع عدة أوامر، إنشاء ملفات. س:
gcc -c asm_functions.S
gcc -c test_asm.c
gcc -o test_asm asm_functions.o test_asm.o
ودول مجلس التعاون الخليجي، أمر واحد يعتني ترجمة الملف .S باستخدام الغاز، وملف .C مع المترجم C دول مجلس التعاون الخليجي، وربط. س مؤقت ناتج ملفات معا باستخدام دينار. يدير دول مجلس التعاون الخليجي عن تلك الأوامر مع أعلام المناسبة افتراضيا.
في بعض النظم (ولكن ليس على لينكس مع تركيب دول مجلس التعاون الخليجي الافتراضي) لديك إضافة البادئة تسطير إلى أسماء وظائف تصديرها في ملف .S (ولكن ليس في .C أو ملفات .H). لذلك كل حالات asm_foo
ستصبح _asm_foo
فقط في ملف .S.
نصائح أخرى
هل تعتبر استخدام التجميع مضمنة ؟ سيكون من الأسهل بكثير من استخدام ملف المجمع.
وتحرير: أيضا، والسبب كنت تحصل أخطاء رابط وربما لأن المترجم C يضيف الرائدة تؤكد على معرفات لرموز الفعلية. حاول إضافة تسطير في ملف التجميع الخاص بك.