Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在程序集中使用外部变量的值_Assembly_Extern_Att - Fatal编程技术网

Assembly 在程序集中使用外部变量的值

Assembly 在程序集中使用外部变量的值,assembly,extern,att,Assembly,Extern,Att,我在汇编中使用.extern变量时遇到了一些问题。如何将它们的值放入寄存器 .extern a, b, c .global main .text main: mov *value of a*, %rax ret 我尝试了以下方法: 在a前面加上符号:.a,$a,a[0],a[1],*a 试图将.extern视为标签.extern+2等' 还尝试了.extern a 我想我不太明白.extern的含义以及如何访问它。我试过阅读英特尔的手册,但我在网上找不到任何关于我需要什么的信息-

我在汇编中使用.extern变量时遇到了一些问题。如何将它们的值放入寄存器

.extern a, b, c
.global main

.text
main:
  mov *value of a*, %rax
    ret
我尝试了以下方法:

  • 在a前面加上符号:
    .a
    $a
    a[0]
    a[1]
    *a
  • 试图将.extern视为标签
    .extern+2
    等'
  • 还尝试了
    .extern a
  • 我想我不太明白.extern的含义以及如何访问它。我试过阅读英特尔的手册,但我在网上找不到任何关于我需要什么的信息-我想我不知道如何正确地写我的问题,因为我不知道什么是
    .extern

    如果有人能告诉我有关它的信息以及如何使用它,我将不胜感激。

    mova(%rip),%rax
    a
    加载

    (mova,%rax也是如此,但不要这样做;您总是希望在x86-64中使用RIP相对寄存器或整数寄存器来寻址静态存储。)

    我认为您缺少的是
    .extern
    与C++中的类似:它声明符号在其他地方定义,在不同的对象文件中。因此,除非您与另一个
    .o
    链接(例如,从编译
    long a=1开始),否则上述内容将进行汇编,但不会链接到可执行文件中在a
    .c

    GAS
    中的。extern
    是不可操作的,因为对于当前asm文件中未定义的符号名,已假定为不可操作。


    也许您想在
    .data
    部分保留一些空间,并在该空间上添加标签,就像C编译器在声明全局变量时所做的那样:

    long a;
    long main(){   // with int main GCC optimizes to loading only EAX
        return a;
    }
    
    使用GCC-O2()编译为以下asm,归结为您希望保留的手写版本的部分:

    main:
            mov     a(%rip), %rax
            ret
    
      .comm   a,8,8    # reserve 8 bytes in the BSS and call it  a
    
    如果我们使用
    long a=1(非零初始值设定项):


    通常,如果您知道要查找什么,您可以从编译器输出中学习asm语法,并编译足够简单的C文件。()但是一些重要的部分(例如,
    .section
    )主要是噪音,如果你知道会发生什么,那么Godbolt会过滤掉它。要查看它,您还必须查看
    .size
    .type
    声明,初学者不必担心这些声明。

    非常感谢您提供的所有信息和帮助!我想我现在更明白了。你能不能给我一些建议,告诉我如何打印登记册的内容,这样我才能真正看到那里发生了什么?我尝试将%ebx中存储的移动到%rsi中并调用syscall,但它不起作用
    write
    使用指向内存中字符串的指针
    strace
    将向您显示,如果您传递一个整数值,则会得到错误指针的
    -EFAULT
    。您可以手动转换:。或者你在找printf。谷歌会告诉你这一点。或者看看C语言的编译器输出。
    .data             # switch to the .data section
    .globl  a         # declare a as externally visible, like a C global not static
    a:                          # a label declares a symbol with address = this position
            .quad   1           # a qword with integer value 1