Sir*_*blk 3 c macos assembly printf nasm
我在Assembly(x86-64)中编写了一个程序,并从C文件包装器调用它来使用printf和scanf函数.但是,当我尝试链接它时,我收到以下错误:
$ 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
Run Code Online (Sandbox Code Playgroud)
我相信这与macho64旗帜有关.如果我使用elf64,它将不会捕获printf或scanf错误.但是,elf64在Mac上是一种不兼容的文件格式(据我所知).
这是我的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;
}
Run Code Online (Sandbox Code Playgroud)
最后这是我的汇编代码(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 ====
Run Code Online (Sandbox Code Playgroud)
为凌乱的代码道歉.这是我的第一个汇编代码程序,我对它很新.我正在开发Mac OSX,据我所知这是Mac OSX特有的问题.谢谢你的帮助.
小智 5
在OS X上,符号以下划线为前缀.
call printf
Run Code Online (Sandbox Code Playgroud)
和
call scanf
Run Code Online (Sandbox Code Playgroud)
需要
call _printf
Run Code Online (Sandbox Code Playgroud)
和
call _scanf
Run Code Online (Sandbox Code Playgroud)
分别; 也
global calcAndPrint
Run Code Online (Sandbox Code Playgroud)
和
calcAndPrint:
Run Code Online (Sandbox Code Playgroud)
应该读
global _calcAndPrint
Run Code Online (Sandbox Code Playgroud)
和
_calcAndPrint:
Run Code Online (Sandbox Code Playgroud)
代替.
(但是,嘿,你可以从你的calcAndPrint()功能被象征化的事实推断出这一点_calcAndPrint).