2013-07-18 15 views
20

Ich bin ein Anfänger in C-Programmiersprache, die vor kurzem habe ich angefangen zu lernen Funktionen, ich habe studiert, dass Funktionen Schlüsselwort return einen Wert im Anrufer Funktion zurückzukehren. Zum Beispiel das folgende Programm.Was bedeutet _AX = 1000 im folgenden C-Programm?

int getVal(){ 
return 1000; 
} 

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

drucken x = 1000

aber ich bin verwirrt, dass (unter Turbo-C-Compiler 32 Bit), warum das folgende Programm wird auch ausgegeben als x = 1000 erzeugen. Bitte erkläre.

int get_val(){ 
_AX = 1000; 
} 

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

Antwort

23

Der "Rückgabewert" wird in einem bestimmten Register zurückgegeben (definiert durch "ABI", die Application Binary-Schnittstelle, die beschreibt, wie Compiler ihren Code generieren sollten), in den meisten x86-Systemen also EAX (32 Bit) oder AX (16 Bit) [nicht gesagt, dass _AX intern nicht wirklich EAX ist].

Dieser Compiler unterstützt offensichtlich die Verwendung eines "Registers" direkt, indem es _AX benannt. Wenn wir also das [E] AX-Register mit einem Wert laden, geben wir im Wesentlichen diesen Wert zurück.

Dies wird definitiv in keinem anderen Compiler funktionieren, obwohl Inline-Assembler das gleiche erreichen kann.

+0

die Syntax wird nicht funktionieren, aber das Konzept funktioniert ... –

12

In C ist _AX ein Pseudoregister. Und wenn Sie AX=1000 tun, ist dieser Wert 1000 aus dem Speicher entnommen wird

Aber es kann nicht wie erwartet in GCC Compiler

Compile und Führen Sie das folgende Programm in Turbo C, werden Sie 35 als Ausgabe erhalten. Es funktioniert möglicherweise nicht in anderen Compilern.

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

Angenommen, die Adresse eines = 1200. Angenommen, die Adresse des Videospeichers = 5500;

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

Dies ist die Art der Ausführung findet statt. Nach dem Kopieren des Wertes 35 auf den Speicherplatz 1200 behält AH den Wert 35.

Dann versucht printf("%d"), den Wert von AH abzurufen und sendet es an den Videospeicher, um es auf dem Bildschirm anzuzeigen.

Wenn wir printf("%d %d", age, salary) verwenden, wird der Wert des Alters auf AH übertragen, bevor dieser Wert zum Senden an den Videospeicher verwendet wird. Dann wird der Wert des Gehalts nach AH verschoben und dann an den Videospeicher gesendet.

Angenommen, Adresse des Alters = 1200; Adresse des Gehalts = 1202; Adresse des Videospeichers = XXXX; (Es wird nach nicht verändert. Von Zeichen auf dem Bildschirm gedruckt, denk nicht viel über diese Adresse Wert)

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

Ich hoffe, das wird helfen, die Lösung für das gegebene Programm zu verstehen.

+1

Ahaa es erinnert mich College-Tag Programmierung, siehe Akku verwendet, weil Rückgabewert sofort zugewiesen, wenn die Steuerung zurück zum Aufruf Funktion so gcc auch verwenden Sie 'a' registrieren. Aber Sache ist, dass dieser Code (syntaxmäßig) vom gcc-Compiler nicht unterstützt wird. Das Schreiben von Assembly-Code in C heißt Inline-Assembly, und sein Compiler ist abhängig (auch in der Syntax) –

+1

@GrijeshChauhan: Teilen, was Sie wissen, ist ein Prime-Faktor Sir, Stimmen und Rep sind sekundär! –

+0

Ah habe ich vergessen, eine weitere Sache zu teilen, versuchen, ausführbare Datei kompiliert von gcc (mit 'objdump exename') oder kompilierten Assembly-Code (' gcc -S code.c') und überprüfen Sie das Register für die Rückkehr. –

7

Laut TC-Compiler (32 Bit), der Rückgabewert einer Funktion wird in Akkumulator (AC) gespeichert, und es kann in TC-Compiler _AX zugegriffen werden, so dass, wenn Sie schreiben:

_AX = 1000; 

bedeutet, dass Sie den Wert 1000 in Accumulator setzen, und wenn die Funktion die Ausführung beendet und die Steuerung die Funktion Aufrufer erreicht, wird der Wert von Accumulator überprüft, und in diesem Fall wird dieser Wert in x gespeichert.

hier die Aussage

x = get_val(); 

wäre einfach

x = 1000; 

aber dies nur in Ihrem Fall wäre, bedeutet in (TC 32-Bit-Windows-Compiler), kann es oder auch nicht für andere Compiler.

+0

Ich frage mich, ob Borland dies immer noch mit C++ Builder erlaubt? Damals, als es veröffentlicht wurde, lief Macs auf PPC-CPUs, die keine AX-, EAX-, usw. Register haben ... –

0

in getval(), 1000 ist in Akkumulator gespeichert, und Getval() wird Kompilierungszeit Warnung, dass die Funktion einen Wert zurückgeben sollte, dann wird x im Hauptspeicher den Wert zurückgegeben oder gespeichert, die ist 1000, deshalb wird es x = 1000 drucken.

+0

Beachten Sie, dass der Akkumulator ein CPU-Register ist und Sie durch Zufall das Ergebnis 1000 erhalten. –

+0

dann warum passiert es durch Glück sogar ... können Sie plz erzählen, dann werden viele von uns darüber erfahren ... – akay

+0

Auf Linux 64bit Compiler Explorer zeigt dies: https://godbolt.org/g/R8ggW9 . Sie können sehen, dass für die korrekte Rückgabe der Wert in eax gespeichert wird. Die Version ohne Rückgabewert wird den in eax enthaltenen Wert übernehmen. Dies könnte der letzte verwendete Wert sein, oder es könnte ein "zufälliger" Restwert sein. –

Verwandte Themen