2013-08-10 11 views
6

Nie mogę skompilować tego programu z samouczka. Powinien wydrukować "Hello World".Jak skompilować ten program za pomocą wbudowanego modułu 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 pod Linuksem daje mi następujący błąd:

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

tam jest również sposób, aby uniknąć określić cudzysłowów dla każdego wiersza?

Chciałbym również wiedzieć, jak zmodyfikować program, aby korzystać z połączenia printf zamiast usługi kernel.

+0

dobrze powinno być 'int main' dla jednego, ASM jest systemem bardzo zależny więc mogłoby to zdecydowanie awarii w zależności od jakiego komputera używasz – aaronman

+2

To wygląda jakbyś kompilacji kodu x86-32 do wyjścia do plik binarny x86-64. – Nayuki

+1

Możesz usunąć 'l's i zmienić'% e * 'na'% r * ', które gdzieś się dostanie. Nie ufaj jednak mojej opinii na ten temat. – Ryan

Odpowiedz

9

P:

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

: popl jest dostępny na x86-32 ale nie x86-64 (posiada popq zamiast). Musisz albo dostosować kod do pracy na x86-64, albo musisz wywołać GCC, aby wygenerować wyjście binarne x86-32.

Zakładając, że chcesz wygenerować x86-32, użyj opcji wiersza polecenia -m32.

P:

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

: Nie. Dzieje się tak, ponieważ __asm__() jest pseudo funkcją, która pobiera argumenty łańcuchowe, więc łańcuch jest zgodny ze składnią C. Zawartość ciągu jest przekazywana do asemblera przy niewielkim przetwarzaniu lub bez przetwarzania.

Należy zauważyć, że w języku C, gdy łańcuchy są zestawione, są łączone. Na przykład "a" "b" jest taki sam jak "ab".

Należy zauważyć, że w składni języka asemblerowego (GAS) można oddzielić instrukcje za pomocą nowej linii lub średnika, na przykład: "movl xxx; call yyy" lub "movl xxx \n call yyy".

P:

how to modify the program to use libc call printf

: Kontynuacja calling convention for C on x86. Przekaż argumenty od prawej do lewej, wywołaj funkcję, a następnie wyczyść stos. Przykład:

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

Pierwsza stawka ..... – Homer6

Powiązane problemy