2013-08-10 34 views
6

Tôi không thể biên dịch chương trình này được lấy từ hướng dẫn. Nó sẽ in "Hello World".Làm thế nào để biên dịch chương trình này với nội tuyến asm?

void main() 
{ 
    __asm__("jmp forward\n\t" 
"backward:\n\t" 
      "popl %esi\n\t" 
      "movl $4, %eax\n\t" 
      "movl $2, %ebx\n\t" 
      "movl %esi, %ecx\n\t" 
      "movl $12, %edx\n\t" 
      "int $0x80\n\t" 
      "int3\n\t" 
"forward:\n\t" 
      "call backward\n\t" 
      ".string \"Hello World\\n\"" 
      ); 
} 

gcc 4.7 dưới Linux mang lại cho tôi những lỗi sau:

gcc hello.c -o hello 
hello.c: Assembler messages: 
hello.c:5: Error: invalid instruction suffix for `pop' 

cũng Có cách nào để tránh để xác định dấu ngoặc kép cho mỗi dòng?

Ngoài ra, tôi muốn biết cách sửa đổi chương trình để sử dụng libc gọi printf thay vì dịch vụ kernel.

+0

cũng cần được 'int main' cho một, asm là hệ thống khá phụ thuộc nên nó chắc chắn có thể sụp đổ tùy thuộc vào máy tính của bạn sử dụng – aaronman

+2

Dường như bạn đang biên soạn x86-32 mã để đầu ra một nhị phân x86-64. – Nayuki

+1

Bạn có thể loại bỏ 'l' và thay đổi '% e *' thành '% r *', được ở đâu đó. Tuy nhiên, đừng tin vào ý kiến ​​của tôi về nó. – Ryan

Trả lời

9

Q:

hello.c: Assembler messages: 
hello.c:5: Error: invalid instruction suffix for `pop' 

Một: popl có sẵn trên x86-32 nhưng không phải trên x86-64 (nó có popq thay). Bạn cần phải thích ứng với mã assembly của bạn để làm việc trên x86-64, hoặc bạn cần gọi GCC để tạo ra đầu ra nhị phân x86-32.

Giả sử bạn muốn tạo x86-32, hãy sử dụng tùy chọn dòng lệnh -m32.

Q:

Is there also a way to avoid to specify double quotes for each line?

Một: Nope. Điều này là do __asm__() là một hàm giả nhận các đối số chuỗi, vì vậy chuỗi theo sau cú pháp C. Các nội dung của chuỗi được chuyển đến trình biên dịch với quá trình xử lý nhỏ hoặc không có.

Lưu ý rằng trong C, khi các chuỗi được đặt cạnh nhau, chúng được nối. Ví dụ: "a" "b" giống với "ab".

Lưu ý rằng trong cú pháp ngôn ngữ assembly (GAS), bạn có thể tách các câu lệnh bằng dòng mới hoặc dấu chấm phẩy, như sau: "movl xxx; call yyy" hoặc "movl xxx \n call yyy".

Q:

how to modify the program to use libc call printf

Một: Thực hiện theo các calling convention for C on x86. Đẩy đối số từ phải sang trái, gọi hàm, sau đó dọn dẹp ngăn xếp. Ví dụ:

pushl $5678 /* Second number */ 
pushl $1234 /* First number */ 
pushl $fmtstr 
call printf 
addl $12, %esp /* Pop 3 arguments of 4 bytes each */ 

/* Put this away from the code */ 
fmtstr: .string "Hello %d %d\n" /* The \n needs to be double-backslashed in C */ 
+0

Tỷ lệ đầu tiên ..... – Homer6

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