Assembly 如何使其在x86-64汇编中工作?

Assembly 如何使其在x86-64汇编中工作?,assembly,x86-64,Assembly,X86 64,最近我在学习组装,现在我有些困惑。我是从学校学的 我的系统的拱门: #uname -m x86_64 这是我的代码: .section .data output: .asciz "This is section %d\n" .section .text .globl _start _start: pushq $1 pushq $output call printf addq $8, %rsp call overhere pushq $3

最近我在学习组装,现在我有些困惑。我是从学校学的

我的系统的拱门:

#uname -m
x86_64
这是我的代码:

.section .data
output:
   .asciz "This is section %d\n"
.section .text
.globl _start
_start:
    pushq $1
    pushq $output
    call printf
    addq $8, %rsp
    call overhere
    pushq $3
    pushq $output
    call printf
    addq $8, %rsp
    pushq $0
    call exit
overhere:
    pushq %rbp
    movq %rsp, %rbp
    pushq $2
    pushq $output
    call printf
    addq $8, %rsp
    movq %rbp, %rsp
    popq %rbp
    ret 
我像这样组装、链接和运行它,得到错误消息:

#as -o calltest.o calltest.s
#ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -o calltest calltest.o
#./calltest 
Segmentation fault

如何使其工作?

x86\u 64
有另一种传递参数,请参见:

下面是您的示例的工作方式:

.section .data
output:
   .asciz "This is section %d\n"
.section .text
.globl _start
_start:
    movq $output, %rdi      # 1st argument
    movq $1, %rsi           # 2nd argument
    xorl %eax, %eax         # no floating point arguments
    call printf
    call overhere
    movq $output, %rdi      # 1st argument
    movq $3, %rsi           # 2nd argument
    xorl %eax, %eax         # no floating point arguments
    call printf
    xor %edi, %edi
    call exit
overhere:
    pushq %rbp
    movq %rsp, %rbp
    movq $output, %rdi      # 1st argument
    movq $2, %rsi           # 2nd argument
    xorl %eax, %eax         # no floating point arguments
    call printf
    movq %rbp, %rsp
    popq %rbp
    ret

x86_64
具有另一种传递参数,请参见:

下面是您的示例的工作方式:

.section .data
output:
   .asciz "This is section %d\n"
.section .text
.globl _start
_start:
    movq $output, %rdi      # 1st argument
    movq $1, %rsi           # 2nd argument
    xorl %eax, %eax         # no floating point arguments
    call printf
    call overhere
    movq $output, %rdi      # 1st argument
    movq $3, %rsi           # 2nd argument
    xorl %eax, %eax         # no floating point arguments
    call printf
    xor %edi, %edi
    call exit
overhere:
    pushq %rbp
    movq %rsp, %rbp
    movq $output, %rdi      # 1st argument
    movq $2, %rsi           # 2nd argument
    xorl %eax, %eax         # no floating point arguments
    call printf
    movq %rbp, %rsp
    popq %rbp
    ret

避免编写汇编代码(特别是在数百行中):编译器的优化效果比您所能做的要好。但是请阅读发出的代码(例如,使用
gcc-O-Wall-fverbose asm-S
),或者在您的C函数中使用
asm
指令。您的那本书是针对x86-64汇编的吗?如果没有,那么如果您想编写64位程序,它可能就没有多大用处了。64位模式下的调用约定与32位模式下的调用约定不同。在32位指令中,使用-m elf_i386标志链接,程序可以正确运行。但是如何让它在64位指令中工作呢?我已经把你的问题缩减到你实际提问的部分。您以前解决的问题不会给您的问题增加太多的洞察力,只会使您的问题看起来脱离主题。避免编写汇编代码(特别是在数百行中):编译器比您能做的更好。但是请阅读发出的代码(例如,使用
gcc-O-Wall-fverbose asm-S
),或者在您的C函数中使用
asm
指令。您的那本书是针对x86-64汇编的吗?如果没有,那么如果您想编写64位程序,它可能就没有多大用处了。64位模式下的调用约定与32位模式下的调用约定不同。在32位指令中,使用-m elf_i386标志链接,程序可以正确运行。但是如何让它在64位指令中工作呢?我已经把你的问题缩减到你实际提问的部分。您以前解决的问题不会给您的问题增加很多洞察力,只会使您的问题看起来脱离主题。FWIW,即x86_64的System V ABI。在Win64中,这将是完全不同的。FWIW,即x86_64的SystemV ABI。在Win64中,这将是完全不同的。