【问题标题】:what is the meaning of _AX = 1000 in the following C program?以下C程序中_AX = 1000是什么意思?
【发布时间】:2013-07-18 11:08:39
【问题描述】:

我是C语言的初学者,最近开始学习函数,研究了函数使用keyword return中返回一个值调用者函数。例如下面的程序。

int getVal(){
 return 1000;
}

int main(){
int x = getVal();
printf("x = %d",x);
return 0;
}

将打印 x = 1000

但我很困惑(在 turbo C 编译器 32 位下)为什么以下程序也产生输出为 x = 1000。请解释一下。

int get_val(){
 _AX = 1000;
}

int main(){
int x = get_val();
printf("x = %d",x);
return 0;
}

【问题讨论】:

    标签: c function


    【解决方案1】:

    在大多数 x86 系统中,即 EAX(32 位)或AX(16 位)[不是说 _AX 实际上不是内部的 EAX]。

    这个编译器显然支持直接使用“寄存器”,将其命名为_AX。因此,通过向 [E]AX 寄存器加载一个值,我们实际上是在返回这个值。

    这绝对不会在任何其他编译器中工作,尽管内联汇编器可以实现同样的事情。

    【讨论】:

      【解决方案2】:

      这里的 C 语言中,_AX 是一个伪寄存器。而当你做AX=1000时,这个值1000取自累加器

      但它在 GCC 编译器中可能无法正常工作

      在 Turbo C 中编译并运行以下程序,您将得到 35 作为输出。它可能不适用于其他编译器。

      #include<stdio.h>  
      int main()  
      {
          int a = 0;  
          a = 35;  
          printf("%d");  
          return 0;
      }  
      

      假设地址 a = 1200。 假设显存地址=5500;

      MOV AH, 35  
      MOV [1200], AH  
      MOV [5500], AH // prints on the screen.  
      

      这是执行发生的方式。将值 35 复制到位置 1200 后,AH 保留值 35。

      然后printf("%d") 尝试从 AH 中获取值并发送到显存以显示在屏幕上。

      如果我们使用printf("%d %d", age, salary),则在使用该值发送到显存之前将年龄值传输到AH。然后将salary的值移动到AH然后发送到显存。

      假设, 年龄地址 = 1200; 工资地址= 1202; 显存地址 = XXXX; (它会根据屏幕上打印的字符数而变化,不要过多考虑这个地址值)

      MOV AH, [1200]
      MOV [XXXX], AH
      MOV AH, [1202]
      MOV [XXXX], AH
      

      我希望这将有助于理解给定程序的解决方案。

      【讨论】:

      • 啊哈,它让我想起了大学时代的编程,请参阅累加器使用,因为当控制返回调用函数时立即分配返回值,所以 gcc 也使用a 寄存器。但问题是 gcc 编译器不支持此代码(语法方面)。用 C 编写汇编代码称为内联汇编,它依赖于编译器(在语法上也是如此)
      • @GrijeshChauhan:分享你所知道的主要因素先生,投票和代表是次要的!
      • 啊我忘了再分享一件事,尝试反汇编由gcc编译的可执行文件(使用objdump exename)或获取编译好的汇编代码(gcc -S code.c)并检查寄存器是否返回。
      【解决方案3】:

      根据 TC 编译器(32 位),函数的返回值存储在 Accumulator (AC) 中,可以在 TC 编译器中使用 _AX 访问,所以当你编写时:

      _AX = 1000;
      

      表示您将值 1000 放入 Accumulator 中,当函数完成执行并且 control 到达 caller 函数时,会检查 Accumulator 的值,在这种情况下,该值将存储在 x 中。

      这里声明

      x = get_val();
      

      很简单

      x = 1000;
      

      但这仅适用于您的情况,意味着在(TC 32 位 Windows 编译器)中,它可能适用于其他编译器,也可能不适用。

      【讨论】:

      • 我想知道 Borland 是否仍然允许在 C++ Builder 中这样做?回到它第一次发布的时候,Mac 是在 PPC CPU 上运行的,它没有 AX、EAX 等寄存器......
      【解决方案4】:

      在 getval() 中,1000 存储在累加器中,getval() 将给出编译时警告,函数应该返回一个值,然后在 main 中,x 将被分配返回或存储在累加器中的值 1000 ,这就是为什么它会打印 x=1000。

      【讨论】:

      • 请注意,累加器是一个 CPU 寄存器,你得到的结果是 1000 很幸运。
      • 那为什么它是靠运气发生的……你能告诉我吗,那么我们中的许多人都会知道的……
      • 在 Linux 64 位编译器资源管理器上显示:godbolt.org/g/R8ggW9。您可以看到,对于正确的返回值,该值存储在 eax 中。没有返回的版本将获取 eax 中的任何值。这可能是最后使用的值,也可能是一些“随机”剩余值。
      • 谢谢,哥们……这对其他人也会很有帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 2011-08-15
      • 2022-01-05
      • 2022-01-08
      • 1970-01-01
      • 2010-12-07
      • 2013-03-09
      相关资源
      最近更新 更多