2013-02-04 3 views
2

j'ai écrit un programme à l'Assemblée (x86-64) et a appelé à partir d'une enveloppe de fichier C utiliser à la fois les fonctions printf et scanf. Cependant quand j'essaye de le lier j'obtiens les erreurs suivantes:reliant printf et Problème scanf dans (x86-64) et le fichier C Assemblée sur Mac OSX

$ nasm -f macho64 -l Parallelograms.lis -o assembly.o Parallelograms.asm 
$ gcc -c -Wall -m64 -o main.o ParallelogramDriver.c 
$ gcc -m64 -o main.out main.o assembly.o 
Undefined symbols for architecture x86_64: 
    "_calcAndPrint", referenced from: 
     _main in main.o 
    "printf", referenced from: 
     calcAndPrint in assembly.o 
    "scanf", referenced from: 
     calcAndPrint in assembly.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 

Je crois qu'il est lié au drapeau macho64. Si je devais utiliser elf64, il n'attraperait pas l'erreur printf ou scanf. Cependant elf64 est un format de fichier incompatible sur Mac (si je comprends bien).

Voici mon fichier C (ParallelogramDriver.c):

#include <stdio.h> 
#include <stdint.h> //For C99 compatability 

extern int calcAndPrint(); 

int main(int argc, char* argv[]) 
{ 
    //Run Assembly Code 
    calcAndPrint(); 

    return 0; 
} 

Et enfin voici mon code de montage (Parallelograms.asm):

;==== Begin code area ==== 
extern printf          ;External C function for output 
extern scanf          ;External C function for input 
extern sin           ;External C function for sin math function 

segment .data          ;Place initialized data in this segment 

    stringData db "%s", 10, 0 
    input1 db "Enter the length of one side of the parallelogram: ", 0 
    input2 db "Enter the length of the second side of the parallelogram: ", 0 
    input3 db "Enter the size in degrees of the included angle: ", 0 

    floatOutput db "You entered: %5.2Lf", 0   ;Don't forget the uppercase L 

    floatData db "%Lf", 0 

segment .bss          ;Place uninitialized data in this segment 

    ;Currently this section is empty 

segment .text          ;Place executable statements in this segment 

    global calcAndPrint 

calcAndPrint:          ;Entry Point Label. 

;==== Necessary Operations! Do not remove! 
    push  rbp         ;Save a copy of the stack base pointer !IMPORTANT 
    push  rdi         ;Save since we will use this for our external printf function 
    push  rsi         ;Save since we will use this for our external printf function 

;==== Enable Floating Point Operations 
    finit           ;Reset pointers to st registers; reset control word, status word, and tag word. 

;============ INPUT 1 ============== 
;==== Ask for first input 
    mov qword rax, 0        ;A zero in rax indicates that printf receives standard parameters 
    mov   rdi, stringData 
    mov   rsi, input1 
    call  printf 

;==== Grab input from Keyboard 
    mov qword rax, 0        ;A zero in rax indicates that printf receives standard parameters 
    mov  rdi, floatData      ;Tell scanf to accept a long float as the data input 
    push qword 0         ;8 byes reserved. Need 10 bytes 
    push qword 0         ;Another 8 bytes reserved for a total of 16 bytes 
    mov  rsi, rsp        ;rsi now points to the 16 bytes we have open. (rsp = Stack Pointer) 
    call  scanf        ;C now uses the scanf function 

;==== Copy 10 byte number into Float space 
    fld tword [rsp]        ;Load Float space and push rsp into the float stack. (braquests de-reference) 

;============ INPUT 2 ============== 
;=== Ask for second input 
    mov qword rax, 0        ;A zero in rax indicates that printf receives standard parameters 
    mov   rdi, stringData 
    mov   rsi, input2 
    call  printf 

;==== Grab input from Keyboard 
    mov qword rax, 0        ;A zero in rax indicates that printf receives standard parameters 
    mov  rdi, floatData      ;Tell scanf to accept a long float as the data input 
    push qword 0         ;8 byes reserved. Need 10 bytes 
    push qword 0         ;Another 8 bytes reserved for a total of 16 bytes 
    mov  rsi, rsp        ;rsi now points to the 16 bytes we have open. (rsp = Stack Pointer) 
    call  scanf        ;C now uses the scanf function 

;==== Copy 10 byte number into Float space 
    fld tword [rsp]        ;Load Float space and push rsp into the float stack. (braquests de-reference) 

;============ INPUT 3 ============== 
;=== Ask for third input 
    mov qword rax, 0        ;A zero in rax indicates that printf receives standard parameters 
    mov   rdi, stringData 
    mov   rsi, input3 
    call  printf 

;==== Grab input from Keyboard 
    mov qword rax, 0        ;A zero in rax indicates that printf receives standard parameters 
    mov   rdi, floatData      ;Tell scanf to accept a long float as the data input 
    push qword 0         ;8 byes reserved. Need 10 bytes 
    push qword 0         ;Another 8 bytes reserved for a total of 16 bytes 
    mov   rsi, rsp       ;rsi now points to the 16 bytes we have open. (rsp = Stack Pointer) 
    call  scanf        ;C now uses the scanf function 

;==== Copy 10 byte number into Float space 
    fld tword [rsp]        ;Load Float space and push rsp into the float stack. (braquests de-reference) 

;============ TEMP ============== 

;============ Output ============== 
    mov qword rax, 0 
    mov   rdi, floatOutput 
    mov qword rax, 1        ;Important for floats??! 
    push qword 0         ;8 bytes reserved 
    push qword 0         ;16 bytes reserved 
    fstp tword [rsp]        ;Pop the fp number from the FP stack into the storage at [rsp] 
    call  printf 

;============ Restore Registers ============ 
    pop rsi 
    pop rdi 
    pop rbp           ;Restore base pointer 

;==== Time to exit this function ==== 
;Prepare to exit from this function 
    mov qword rax, 0        ;A zero in rax is the code indicating a successful execution. 
    ret            ;ret pops the stack taking away 8 bytes 

;==== End of function calcAndPrint ==== 

Toutes mes excuses pour le code désordre. C'est mon premier programme de code d'assemblage et j'en suis très nouveau. Je développe sur Mac OSX et à ma connaissance c'est un problème spécifique à Mac OSX. Merci de votre aide.

+0

Avez-_you_ écrit le programme de montage ou CTRL + C CTRL + V'd il :-P –

+0

je l'ai écrit, faisant référence à un code très exemple notre professeur nous a fourni. Je l'ai copié et collé ici. C'est mon premier programme d'assemblage, donc je m'excuse pour le code grossier. – Sirusblk

Répondre

4

Sur OS X, les symboles sont préfixés par un trait de soulignement.

call  printf 

et

call  scanf 

besoin d'être

call  _printf 

et

call  _scanf 

respectivement; aussi

global calcAndPrint 

et

calcAndPrint: 

devrait lire

global _calcAndPrint 

et

_calcAndPrint: 

à la place.

(Mais bon, vous auriez pu déduire cela du fait que votre fonction calcAndPrint() a été symbolisée en _calcAndPrint).

+0

Certains de ces comportements peuvent être contrôlés avec '-fleading-underscore'. Mais dans ce cas, seulement pour 'calcAndPrint'. Les symboles fournis par le système d'exploitation vont rester bloqués avec un '_'. Ajout –

+2

'--prefix _' à la ligne de commande de Nasm devrait (?) Résoudre ce problème (comme une alternative à l'ajout des underscores dans votre source de .asm. –

+0

De plus, à moins que c'est nouveau pour x64, C ne connaît pas 'tword' -.. essayez de le remplacer par 'qword' ... –