C 프로그램 (GNU 어셈블러)과 함께 사용하기 위해 어셈블리 루틴을 어떻게 컴파일합니까?

StackOverflow https://stackoverflow.com/questions/808948

문제

헤더 파일을 만들어 C 프로그램에서 사용하려는 어셈블리 기능 세트가 있습니다. 예를 들어, 실제 어셈블리 루틴 및 ASM_Functions.h를 정의하는 ASM_FINCTION.S가있는 경우 기능에 대한 프로토 타입과 필요한 일부 표준 #Define 's가 필요합니다. 내 목표는 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 : / * C 호출 규칙에 대한 적절한 스택 조작이있는 ASM 코드 * / ret

test__asm.c :


 #include "asm_foo.h"

int main () {uint8_t res = asm_foo (1, 2, 3); 반환 0; }

이와 같은 상황에서 프로그램을 링크를 컴파일하는 올바른 방법은 무엇입니까? 나는 다음과 같은 것을 시도하고 있었다 :


gas -o asm_foo.o asm_foo.s
gcc -o test_asm test_asm.c

그러나 나는 여전히 내 어셈블리 루틴이 정의되지 않았다고 GCC로부터 링커 오류를받습니다. 이 만난 예가 상황을 설명하기에 충분하기를 바랍니다.

감사!

편집하다:

다음은 단일 명령으로 컴파일 할 때 출력 스 니펫입니다.


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 toPCI_FUNCTION_ID'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0xa): undefined reference toREAD_CONFIG_BYTE'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x18): undefined reference toPCI_BIOS_FUNCTION_INT'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x1b): undefined reference toBAD_REGISTER_NUMBER'
/tmp/ccY0SmMN.o: In function _pci_bios_read_word':
(.text+0x30): undefined reference toPCI_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와 함께 Capital S.가있는 어셈블리 파일 확장. .s 파일의 ASM_CONST_1.

단일 명령으로 컴파일 :

gcc -o test_asm asm_functions.S test_asm.c

또는 대안으로 여러 명령으로 컴파일하여 .o 파일을 만듭니다.

gcc -c asm_functions.S
gcc -c test_asm.c
gcc -o test_asm asm_functions.o test_asm.o

단일 명령 GCC는 가스를 사용하여 .S 파일을 컴파일하는 것을 관리하고, GCC의 C 컴파일러가있는 .C 파일 인. GCC는 기본적으로 적절한 플래그로 모든 명령을 실행합니다.

일부 시스템에서 (기본 GCC 설치가있는 Linux에서는 아님) .S 파일의 내보내기 기능 이름으로 밑줄을 선방해야합니다 (.C 또는 .h 파일은 아님). 그래서 모든 인스턴스 asm_foo 될 것입니다 _asm_foo .s 파일에서만.

다른 팁

당신은 고려 했습니까? 인라인 어셈블리 사용? 어셈블러 파일을 사용하는 것보다 훨씬 쉬울 것입니다.

편집 : 또한 링커 오류를 얻는 이유는 아마도 C 컴파일러가 실제 기호에 대한 식별자에 선행 밑줄을 추가하기 때문일 수 있습니다. 어셈블리 파일에 밑줄을 추가하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top