库函数(C)如何调用gnu汇编语言?

时间:2013-04-15 10:14:29

标签: assembly x86-64 gas

我编译了一段代码。

.data
ssttrr:
.string "%d\n"
.text
.globl main
main:
mov $213, %rdx
push %rdx
push $ssttrr
call _printf
add  $8, %rsp

或者它

.global main

    .text
main:

push    %rax                    # caller-save register
push    %rcx                    # caller-save register

mov     $format, %rdi           # set 1st parameter (format)
mov     %rax, %rsi              # set 2nd parameter (current_number)
xor     %rax, %rax              # because printf is varargs
call    printf                  # printf(format, current_number)

pop     %rcx                    # restore caller-save register
pop     %rax                    # restore caller-save register

mov     %rax, %rdx              # save the current number
mov     %rbx, %rax              # next number is now current
add     %rdx, %rbx              # get the new next number
dec     %ecx                    # count down
jnz     print                   # if not done counting, do some more

pop     %rbx                    # restore rbx before returning


mov  $60, %rax
xor  %rdi, %rdi
syscall

format:
    .asciz  "%20ld\n"

为什么“格式”在.text字段中?

gcc -nostdlib file.s -o program

为什么会出错?

  

/universe/earth/asm/file.s:14:未定义引用`_printf'   collect2:ld返回1退出状态

如何解决此错误?

如果是,则所有代码都有效。为什么???

.global main

    .text
main:
    push    %rbx                    # we have to save this since we use it

    mov     $90, %ecx               # ecx will countdown to 0
    xor     %rax, %rax              # rax will hold the current number
    xor     %rbx, %rbx              # rbx will hold the next number
    inc     %rbx                    # rbx is originally 1
print:
    # We need to call printf, but we are using eax, ebx, and ecx.  printf
    # may destroy eax and ecx so we will save these before the call and
    # restore them afterwards.

    push    %rax                    # caller-save register
    push    %rcx                    # caller-save register

    mov     $format, %rdi           # set 1st parameter (format)
    mov     %rax, %rsi              # set 2nd parameter (current_number)
    xor     %rax, %rax              # because printf is varargs
    call    printf                  # printf(format, current_number)

    pop     %rcx                    # restore caller-save register
    pop     %rax                    # restore caller-save register

    mov     %rax, %rdx              # save the current number
    mov     %rbx, %rax              # next number is now current
    add     %rdx, %rbx              # get the new next number
    dec     %ecx                    # count down
    jnz     print                   # if not done counting, do some more

    pop     %rbx                    # restore rbx before returning
    ret
 format:
    .asciz  "%20ld\n"

为什么函数print:在主域中没有被调用?

cpy:intel-64 os:debian

2 个答案:

答案 0 :(得分:2)

  

为什么“格式”在.text字段中?

汇编中的

.text意味着“代码部分”

  

gcc -nostdlib file.s -o program   为什么我会收到错误?   /universe/earth/asm/file.s:14:未定义引用`_printf'collect2:ld返回1退出状态

你没有链接printf所在的标准库(-nostdlib选项):链接器找不到它

  

如何解决此错误?

显式链接标准库(stdlib),或链接另一个提供printf实现的库,或删除-nostdlib开关

  

为什么函数print:在主域中没有被调用?

“print”只是一个标签:你可以调用它,jmp到它,或者只是让程序的控制流进入它,就像在这种情况下一样。 (我可以说打印不是“功能”,因为它没有正确的序幕)。

我可以建议你介绍一些装配吗?

或者您可以在互联网上找到许多其他人

答案 1 :(得分:1)

为什么“格式”在.text字段中? 目前还不清楚你在这里问的是什么,但我认为你在问两件事,压缩在这里:

mov     $format, %rdi           # set 1st parameter (format)

format:
    .asciz  "%20ld\n"

.text部分,您引用的是format标签。稍后,您可以定义format标签。

为什么会收到错误? 您正在指定编译器选项-nostdlib,该选项排除了通常包含的库,包括printf函数。

为什么功能打印:不在主域中调用? 没有功能打印,但有一个标签, 正在使用:

jnz     print                   # if not done counting, do some more

它似乎是基于%ecx的循环的终止点,从0x90到0计数。