2011-08-25 45 views
48

Tôi đang chơi xung quanh với một số mã asm, và một cái gì đó đang làm phiền tôi.Làm cách nào để biên dịch asm do GCC tạo ra?

tôi biên dịch này:

#include <stdio.h> 

int main(int argc, char** argv){ 
    printf("Hello World\n"); 
    return 0; 
} 

với gcc file.c -S -o file.S này tạo ra một chút mảnh đẹp mã asm:

.cstring 
LC0: 
    .ascii "Hello World\0" 
    .text 
.globl _main 
_main: 
LFB3: 
    pushq %rbp 
LCFI0: 
    movq %rsp, %rbp 
LCFI1: 
    subq $16, %rsp 
LCFI2: 
    movl %edi, -4(%rbp) 
    movq %rsi, -16(%rbp) 
    leaq LC0(%rip), %rdi 
    call _puts 
    movl $0, %eax 
    leave 
    ret 
LFE3: 
    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 
EH_frame1: 
    .set L$set$0,LECIE1-LSCIE1 
    .long L$set$0 
LSCIE1: 
    .long 0x0 
    .byte 0x1 
    .ascii "zR\0" 
    .byte 0x1 
    .byte 0x78 
    .byte 0x10 
    .byte 0x1 
    .byte 0x10 
    .byte 0xc 
    .byte 0x7 
    .byte 0x8 
    .byte 0x90 
    .byte 0x1 
    .align 3 
LECIE1: 
.globl _main.eh 
_main.eh: 
LSFDE1: 
    .set L$set$1,LEFDE1-LASFDE1 
    .long L$set$1 
LASFDE1: 
    .long LASFDE1-EH_frame1 
    .quad LFB3-. 
    .set L$set$2,LFE3-LFB3 
    .quad L$set$2 
    .byte 0x0 
    .byte 0x4 
    .set L$set$3,LCFI0-LFB3 
    .long L$set$3 
    .byte 0xe 
    .byte 0x10 
    .byte 0x86 
    .byte 0x2 
    .byte 0x4 
    .set L$set$4,LCFI1-LCFI0 
    .long L$set$4 
    .byte 0xd 
    .byte 0x6 
    .align 3 
LEFDE1: 
    .subsections_via_symbols 

vấn đề tiếp theo của tôi thực sự, làm thế nào để biên dịch ra đây là, và tôi có thể làm cho GCC làm điều đó cho tôi?

Trả lời

61

Có, Bạn có thể sử dụng gcc để biên dịch mã asm của mình. Sử dụng -c để biên soạn như sau:

gcc -c file.S -o file.o 

Điều này sẽ cung cấp tệp đối tượng có tên là file.o. Để gọi trình liên kết thực hiện theo lệnh sau đây:

gcc file.o -o file 
+9

bạn cũng có thể chỉ sử dụng tệp 'gcc.S -o' –

+0

còn về"> as -o hello.o hello.s "? như được chỉ ra bởi https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html. Có vẻ như thứ tự của quá trình là tiền xử lý (* .i-file), biên dịch (*. S-file), lắp ráp (*. O-file) và liên kết (* .exe-file). – user1677716

3

Có, gcc cũng có thể biên dịch mã nguồn lắp ráp. Ngoài ra, bạn có thể gọi as, là bộ lắp ráp. (Gcc chỉ là một "tài xế" chương trình sử dụng công nghệ tự động gọi trình biên dịch C, C++, lắp ráp, mối liên kết, vv ..)

+1

Làm thế nào để tìm ra cách gcc sẽ sử dụng như là? –

+0

Ngoài ra, tôi có Intels icc nằm arround, những gì lắp ráp để họ sử dụng? –

+4

@Martin, yêu cầu 'gcc -v' thuật lại hành động của nó. –

7

Bạn có thể nhúng mã lắp ráp vào chương trình C bình thường. Đây là một số introduction tốt. Sử dụng cú pháp thích hợp, bạn cũng có thể cho GCC bạn muốn tương tác với các biến khai báo trong C. Chương trình dưới đây chỉ thị gcc rằng:

  • eax sẽ foo
  • ebx sẽ thanh
  • giá trị trong eax sẽ được lưu trữ trong foo sau khi mã lắp ráp thực hiện

\ n

int main(void) 
{ 
     int foo = 10, bar = 15; 
     __asm__ __volatile__("addl %%ebx,%%eax" 
          :"=a"(foo) 
          :"a"(foo), "b"(bar) 
          ); 
     printf("foo+bar=%d\n", foo); 
     return 0; 
} 
37

gcc có thể sử dụng tệp lắp ráp làm đầu vào và gọi trình kết hợp nếu cần. Có một sự tinh tế, mặc dù:

  • Nếu tên tệp có đuôi ".s" (chữ thường 's'), sau đó gcc gọi là lắp ráp.
  • Nếu tên tệp có đuôi ".S" (chữ hoa 'S'), sau đó gcc áp dụng tiền xử lý C vào file nguồn (tức là nó nhận ra chỉ thị như #if và thay thế macro), và sau đó gọi là lắp ráp trên kết quả.

Vì vậy, trên cơ sở nói chung, bạn muốn làm điều như thế này:

gcc -S file.c -o file.s 
gcc -c file.s 
+0

Điều này có vẻ như hoạt động nhưng tôi nhận được thông báo lỗi: 'Tệp Mach-o không đúng định dạng' –

+0

Tôi nghĩ bạn phải sử dụng tiền tố '.S' (chữ hoa) nếu không gcc phát hiện một loại tệp khác (không thành công với' .asm' chẳng hạn) –

0
nasm -f bin -o 2_hello 2_hello.asm 
+2

Đây là một câu trả lời khá ngắn. Bạn có thể thêm một số lời giải thích, xin vui lòng? Có lẽ bạn có thể cho chúng tôi biết các thông số và những gì bạn làm khác so với các câu trả lời khác. – GameDroids

2

Nếu bạn có tập tin main.s. bạn có thể tạo tập tin đối tượng bằng cách GCC và cũng as

# gcc -c main.s 
# as main.s -o main.o 

kiểm tra liên kết này, nó sẽ giúp bạn tìm hiểu một số binutils của GCC http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/

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