我用GAS x86-64汇编语言编写了主要功能,该功能从用户的两个字符串的大小开始并将它们保存在堆栈中,并且还从用户那里获得一个选项(50到55之间的整数)。主要函数需要另一个函数-func_select,该函数将堆栈上两个字符串的地址以及通过用户传递的选项作为参数作为参数,并根据该选项对这些字符串进行一些操作。我对func_select没有任何问题。但是我以前有问题,用scanf读取两个字符串及其大小。我花了很多时间在Google上搜索堆栈溢出,却找不到能解决我的奇怪包的东西。所以,我的主要功能是:
.data
d: .string "%d"
s: .string "%s"
zeroStr: .string "\0"
.text
.global main
.type main,@function
main:
pushq %rbp
movq %rsp,%rbp #frame pointer to the stack
xorq %rax,%rax #putting zero for scanf
subq $8,%rsp #allocating place for n1
movq $d, %rdi #first argument for scanf
movq %rsp,%rsi #second argument fro scanf
call scanf
popq %r14 #saving n1 to this register(scanf put return value to the stack on address that rsp holds
pushq $zeroStr #at the end of the string will be null terminated character
subq %r14,%rsp #allocating a place for pstring1(r14 holds its size)
xorq %rax,%rax
movq $s,%rdi #first scanf argument
movq %rsp,%rsi #second scanf argument
call scanf
incq %r14 #for '\0'
pushq %r14 #before the string we save its size
movq %rsp,%r12 #store to %r12 the pointer to ptstring1
xorq %rax,%rax #putting zero for scanf
subq $8,%rsp #allocating place for n2
movq $d, %rdi #first argument for scanf
movq %rsp,%rsi #second argument for scanf(a pointer to the place where the input will be saved
call scanf
popq %r14 #put to r14 an input(n2- size of the second string) ------------HERE I POP INCORRECT VALUE. THE USER PUTS ANOTHER NUMBER------
pushq $zeroStr #for '\0'
subq %r14,%rsp #allocating a place for pstring2
xorq %rax,%rax
movq $s,%rdi
movq %rsp,%rsi
call scanf #-----HERE I GET A SEGMENTATION FAULT------
incq %r14 #for '\0'
pushq %r14
movq %rsp,%r13 #store to %r13 the pointer to ptstring2
xorq %rax,%rax
movq $d,%rdi #the format of the printf option(first scanf argument)
subq $8,%rsp #allocationg place for input- the option
movq %rsp,%rsi #second scanf argument
call scanf
popq %rdi #a first parametr for function func_Select(an option)
movq %r12,%rsi #sec par for func_Select
movq %r13,%rdx #third par for func_Select
call func_select
#end up
addq $8,%rsp
addq (%r13),%rsp
addq (%r12),%rsp
popq %rbp
ret
我遇到了细分错误:
Program received signal SIGSEGV, Segmentation fault.
main () at main.s:41
41 call scanf
更为珍贵的说,我的程序首先从用户扫描第一个字符串n1的大小(我将此字符串称为pstring1),然后再扫描pstring1。然后,它扫描第二个字符串n2的大小(我称此字符串为pstring2),然后扫描pstring2。 字符串保存在堆栈中,并且在每个字符串之前(在接下来的8个字节处,在堆栈中字符串的第一个字符以下)保存其大小(相应地保存n1或n2)。 我调用scanf读取pstring2时,发生了错误隔离错误。从我的保留中,当我以前使用scanf在堆栈上获取n2,然后从堆栈中弹出它时(我在注释中添加了------------我弹出错误的值。用户输入另一个数字----在代码的这一行)到%r14,我得到了另一个号码,而不是我从用户那里读到的那个号码。一些奇怪的价值,比我所说的还要大。 我不明白我在做什么错。我使用scanf正确,遵循x86 GAS注册约定等。如果有人可以帮助我,我将非常高兴。 预先谢谢你。