我正在学习在Linux(gcc)上的x86-64程序集(AT& T)中进行编码,并且在这个简单的代码中无法找到我的分段错误的解决方案。我见过一些关于堆栈对齐的问题;然而,即使我尝试8美元或16美元,这也会失败:
student.h
我写的其他程序似乎在调用printf后工作正常。上面的代码有什么问题?无论有没有退出调用,代码都会失败。这和下面的代码失败了。我使用编译:
.global main
main:
#prologue
movq %rsp, %rbp #initialise base pointer
#reserve memory for subroutine
subq $8, %rsp #the line causing the segfault
exit:
movq $0, %rdi
call exit
整个代码:
gcc -o test test.s
使用(gdb)x / i $ pc时的主代码错误:
.text
formatStr: .asciz "%ld"
resultStr: .asciz "The result is: %d\n"
q1: .asciz "Enter the base: "
q2: .asciz "Enter the exponent: "
#qTable2: #look up table for correct string during scanf
# .asciz q1
# .asciz q2
qTable: #alternative look up table
.quad base
.quad exponent
base:
movq $q1, %rdi
ret
exponent:
movq $q2, %rdi
ret
###################
# Subroutine: pow
# Function: Power an integer base to an exponent
# Inputs: uint base, int exponent(natural)
# Outputs: int result
##################
pow:
#prologue
pushq %rbp #store caller base pointer
movq %rsp, %rbp
movq $1, %rax #reset result
movq $0, %rbx #initialise loop
loop1:
imulq %rdi
incq %rbx
cmp %rsi, %rbx #compare loop interator to exponent
jle loop1
#epilogue
movq %rbp, %rsp #clear local variables from stack
pop %rbp #restore caller base pointer
ret
.global main
###################
# Subroutine: Main
# Function: Application entry point
###################
main:
#prologue
pushq %rbp
movq %rsp, %rbp #initialise base pointer
#reserve memory for subroutine
subq $8, %rsp
#Gather the inputs from the user
movq $0, %rbx #loop counter
#inputAcq:
#Call printf using correct question
movq %rax, %rsi #move result into argument 2
movq qTable(,%rbx,8), %rdi #format string as argument 1
call *%rdi
movq $0, %rax #no vector registers
call printf
leaq -16(%rbp,%rbx,8), %rsi #Argument 2
movq formatStr, %rdi #Argument 1
movq $0, %rax #no vector registers
call scanf
incq %rbx #increment loop counter
cmp $1, %rbx #check if more inputs are necessary else continue
jl inputAcq
#Call pow
movq -8(%rbp), %rsi #the exponent
movq -16(%rbp), %rdi #the base
call pow
#Call printf
movq %rax, %rsi #move result into argument 2
movq $resultStr, %rdi #format string as argument 1
movq $0, %rax #no vector registers
call printf
#exit program without errors
exit:
movq $0 , %rdi
call exit
答案 0 :(得分:1)
subq $8, %rsp #the line causing the segfault
由于上面的指令没有引用内存,无法 那条指令发生了分段错误。
您可能会错误地解释您实际看到的内容。你应该
P.S。要查找发生段错误的实际指令,请在gdb
下运行程序,并在发生段错误后执行(gdb) x/i $pc
命令。
答案 1 :(得分:1)
In [16]: np.subtract.outer(q, q)
Out[16]:
array([[ 0, -4, -8],
[ 4, 0, -4],
[ 8, 4, 0]])
您已经编写了一个包含推送返回地址的无限循环。当你用完堆栈时,它最终会出现段错误。
在您自己的代码中为exit: # target of the CALL instruction
movq $0 , %rdi
call exit
标签使用其他名称。 exit
可以正常工作,并且在调试时不会显示为标签。
有关GNU中本地标签的更多信息,请参阅this answer。