在GAS x86-64程序集中使用scanf的奇怪错误

时间:2018-12-10 11:14:07

标签: debugging assembly scanf x86-64 gas

我用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注册约定等。如果有人可以帮助我,我将非常高兴。 预先谢谢你。

0 个答案:

没有答案