【问题标题】:Getting address of data variable in x86 AT&T Assembly在 x86 AT&T 程序集中获取数据变量的地址
【发布时间】:2014-06-16 11:55:12
【问题描述】:

Possible duplicate exist,但我不知道如何将这个或其他解决方案应用于类似问题,所以我来了。

我正在创建一个函数,该函数在 x86 AT&T 程序集中将整数作为字符串返回。

我有这段代码来声明变量resdes

        .data
    .align 4
resdes: .long 12

resdes 现在指向一个内存位置,后跟 11 个其他字节供我使用(我理解正确吗?)。

我想一次将一位数字从整数加载到字节中。这是我的代码:

ifd:
    movl        (%esp, %ecx), %eax  //This loads %eax with my int
    movl        resdes, %ecx     //This is incorrect and causes errors later
    inc         %ecx
    movl        $10, %ebx        //Division by 10 to basically do a modulo operation
    cdq

divloop:
    div         %ebx

    movb        %dl, (%ecx)      //This is where I move the digit into the memory
                                 //And here I get the ERROR because (%ecx) does 
                                 //not contain the proper address

    inc         %ecx             //And set the pointer to point to the next byte

    cmp         $0, %eax         //If there are noe more digits left we are finished
    je          divfinish1

    jmp         divloop          //I leave out alot of the code that I know 
                                 //work because it's not relevant

我的问题是将resdes 的实际地址放入%ecxregister,即上述代码的第一行。据我所知,该行将resdes-address 的内容移动到%ecx,这不是我想要的。

【问题讨论】:

    标签: memory assembly gnu-assembler att


    【解决方案1】:

    问题似乎是在执行除法后您没有将除法的结果保存在 %ebx 寄存器中,因此除法会一直持续下去,总是返回相同的模数和除法结果——你保持在划分相同的数字。反过来,这会导致 SIGSEGV,因为结果最终会溢出为结果保留的 12 个字节。这是一个可能的解决方案:

    ifd:
        movl        resdes, %ecx   
        inc         %ecx
        movl        $10, %ebx       
        cdq
    
    divloop:
        div         %ebx
    
        movb        %dl, (%ecx)   
        inc         %ecx    
    
        movl        %eax,%ebx         //Stores the new value in %ebx
    
        cmp         $0, %eax        
        je          divfinish1
    
        jmp         divloop          
    

    resdes 现在指向一个内存位置,后跟 11 个其他可用字节供我使用(我理解正确吗?)。

    是的。

    【讨论】:

    • 通过加载 %eax 更新了我的代码,因此更清楚实际问题是什么,因为这并不能解决它
    【解决方案2】:

    好的,所以我自己“解决”了这个问题。我基本上将内存存储一起删除,而是使用堆栈。

    这并没有回答我关于如何正确获取地址的问题,但它使我的代码工作,所以我把它放在这里。

    ifd:
    
        movl        (%esp, %ecx), %eax
        add         $4, %ecx
        movl        $10, %ebx
        pushl       $0
    
    divloop:
        cdq
        div         %ebx
    
        add         $48, %edx
        pushl       %edx
    
        cmp         $0, %eax
        je          divfinish1
    
        jmp         divloop
    
    divfinish1:
        movl        tempb, %ebx
    
    divfinish2:
        popl        %edx
    
        cmp         $0, %edx
        je          divfinish3    //this is the end
    
        movb        %dl, (%ebx)
        inc         %ebx
    
        jmp         divfinish2
    

    【讨论】:

      【解决方案3】:

      您希望使用将在“组装时”计算的常数加载 ECX。所以使用 '$' 作为前缀:movl $resdes, %ecx 以获取 resdes 的偏移量为常量。

      【讨论】:

      • 谢谢,试试这个
      猜你喜欢
      • 2018-05-12
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 2013-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多