バイト数が足されるはずなのにひかれている?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たから

バイト数が足されるはずなのにひかれている?

#1

投稿記事 by たから » 6年前

コード:


#include <stdio.h> 
int main( void ) 
{    
      int a;    
      int *b;    
printf("%p\n", &a);    
b = &a;    
*b = 100;    
printf("%d\n", a);    
printf("%p\n", &b);    
printf("%p\n", b);    
printf("%d\n", *b);   
 
return 0;
 } 

プログラムの問題で
&aの表示が0x7FF7C8であるとき、
a=100
b=0x7FF7C8
*b = 100
で、&bには0x7FF7C8にintのバイト数をたすので0x7FF7CCだと思ったのですが解答には0x7FF7C4と書かれていて解説にはintなので4バイト分離れて確保されるとありました
なぜひいているのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: バイト数が足されるはずなのにひかれている?

#2

投稿記事 by みけCAT » 6年前

コンパイラの実装に依存するので本当のことはコンパイラの作者に聞かないとわからないと思いますが、
上位から下位に向かって伸びるx86のスタックに合わせたということが考えられます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Math

Re: バイト数が足されるはずなのにひかれている?

#3

投稿記事 by Math » 6年前

Windows10,VS2017Community では

c.bat

コード:

rem コンパイル後リンク
cl /Fac1.asm /TC c1.c
rem 実行結果
c1.exe
c1.c

コード:

#define _CRT_SECURE_NO_WARNINGS //セキュリティ警告抑制
 
#include <stdio.h> 

int main( void ) 
{    
    int a;                
    int *b;                 

    printf("%p\n", &a);    
    b = &a;                
    *b = 100;    
    printf("%d\n", a);    
    printf("%p\n", &b);    
    printf("%p\n", b);    
    printf("%d\n", *b);   
 
    return 0;
}

実行結果

コード:

G:\z18c\0123>c

G:\z18c\0123>rem コンパイル後リンク

G:\z18c\0123>cl /Fac1.asm /TC c1.c
Microsoft(R) C/C++ Optimizing Compiler Version 19.11.25508.2 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

c1.c
Microsoft (R) Incremental Linker Version 14.11.25508.2
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:c1.exe
c1.obj

G:\z18c\0123>rem 実行結果

G:\z18c\0123>c1.exe
00CFFECC
100
00CFFED0
00CFFECC
100

G:\z18c\0123>
c1.asm  アセンブラー出力

コード:

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.11.25508.2 

	TITLE	G:\z18c\0123\c1.c
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

_DATA	SEGMENT
$SG5440	DB	'%p', 0aH, 00H
$SG5441	DB	'%d', 0aH, 00H
$SG5442	DB	'%p', 0aH, 00H
$SG5443	DB	'%p', 0aH, 00H
$SG5444	DB	'%d', 0aH, 00H
_DATA	ENDS
PUBLIC	___local_stdio_printf_options
PUBLIC	__vfprintf_l
PUBLIC	_printf
PUBLIC	_main
EXTRN	___acrt_iob_func:PROC
EXTRN	___stdio_common_vfprintf:PROC
_DATA	SEGMENT
COMM	?_OptionsStorage@?1??__local_stdio_printf_options@@9@9:QWORD							; `__local_stdio_printf_options'::`2'::_OptionsStorage
_DATA	ENDS
; Function compile flags: /Odtp
_TEXT	SEGMENT
_a$ = -8						; size = 4
_b$ = -4						; size = 4
_main	PROC
; File g:\z18c\0123\c1.c
; Line 6
	push	ebp
	mov	ebp, esp
	sub	esp, 8
; Line 10
	lea	eax, DWORD PTR _a$[ebp]
	push	eax
	push	OFFSET $SG5440
	call	_printf
	add	esp, 8
; Line 11
	lea	ecx, DWORD PTR _a$[ebp]
	mov	DWORD PTR _b$[ebp], ecx
; Line 12
	mov	edx, DWORD PTR _b$[ebp]
	mov	DWORD PTR [edx], 100			; 00000064H
; Line 13
	mov	eax, DWORD PTR _a$[ebp]
	push	eax
	push	OFFSET $SG5441
	call	_printf
	add	esp, 8
; Line 14
	lea	ecx, DWORD PTR _b$[ebp]
	push	ecx
	push	OFFSET $SG5442
	call	_printf
	add	esp, 8
; Line 15
	mov	edx, DWORD PTR _b$[ebp]
	push	edx
	push	OFFSET $SG5443
	call	_printf
	add	esp, 8
; Line 16
	mov	eax, DWORD PTR _b$[ebp]
	mov	ecx, DWORD PTR [eax]
	push	ecx
	push	OFFSET $SG5444
	call	_printf
	add	esp, 8
; Line 18
	xor	eax, eax
; Line 19
	mov	esp, ebp
	pop	ebp
	ret	0
_main	ENDP
_TEXT	ENDS
; Function compile flags: /Odtp
;	COMDAT _printf
_TEXT	SEGMENT
__Result$ = -8						; size = 4
__ArgList$ = -4						; size = 4
__Format$ = 8						; size = 4
_printf	PROC						; COMDAT
; File c:\program files (x86)\windows kits\10\include\10.0.15063.0\ucrt\stdio.h
; Line 952
	push	ebp
	mov	ebp, esp
	sub	esp, 8
; Line 955
	lea	eax, DWORD PTR __Format$[ebp+4]
	mov	DWORD PTR __ArgList$[ebp], eax
; Line 956
	mov	ecx, DWORD PTR __ArgList$[ebp]
	push	ecx
	push	0
	mov	edx, DWORD PTR __Format$[ebp]
	push	edx
	push	1
	call	___acrt_iob_func
	add	esp, 4
	push	eax
	call	__vfprintf_l
	add	esp, 16					; 00000010H
	mov	DWORD PTR __Result$[ebp], eax
; Line 957
	mov	DWORD PTR __ArgList$[ebp], 0
; Line 958
	mov	eax, DWORD PTR __Result$[ebp]
; Line 959
	mov	esp, ebp
	pop	ebp
	ret	0
_printf	ENDP
_TEXT	ENDS
; Function compile flags: /Odtp
;	COMDAT __vfprintf_l
_TEXT	SEGMENT
__Stream$ = 8						; size = 4
__Format$ = 12						; size = 4
__Locale$ = 16						; size = 4
__ArgList$ = 20						; size = 4
__vfprintf_l PROC					; COMDAT
; File c:\program files (x86)\windows kits\10\include\10.0.15063.0\ucrt\stdio.h
; Line 640
	push	ebp
	mov	ebp, esp
; Line 641
	mov	eax, DWORD PTR __ArgList$[ebp]
	push	eax
	mov	ecx, DWORD PTR __Locale$[ebp]
	push	ecx
	mov	edx, DWORD PTR __Format$[ebp]
	push	edx
	mov	eax, DWORD PTR __Stream$[ebp]
	push	eax
	call	___local_stdio_printf_options
	mov	ecx, DWORD PTR [eax+4]
	push	ecx
	mov	edx, DWORD PTR [eax]
	push	edx
	call	___stdio_common_vfprintf
	add	esp, 24					; 00000018H
; Line 642
	pop	ebp
	ret	0
__vfprintf_l ENDP
_TEXT	ENDS
; Function compile flags: /Odtp
;	COMDAT ___local_stdio_printf_options
_TEXT	SEGMENT
___local_stdio_printf_options PROC			; COMDAT
; File c:\program files (x86)\windows kits\10\include\10.0.15063.0\ucrt\corecrt_stdio_config.h
; Line 85
	push	ebp
	mov	ebp, esp
; Line 87
	mov	eax, OFFSET ?_OptionsStorage@?1??__local_stdio_printf_options@@9@9 ; `__local_stdio_printf_options'::`2'::_OptionsStorage
; Line 88
	pop	ebp
	ret	0
___local_stdio_printf_options ENDP
_TEXT	ENDS
END
となりますね。

スタックは上位アドレスから下位に伸び ヒープ領域(mallocで確保した領域など)は下位アドレスから上位にのびます。

Math

Re: バイト数が足されるはずなのにひかれている?

#4

投稿記事 by Math » 6年前

c1.c

コード:

#define _CRT_SECURE_NO_WARNINGS //セキュリティ警告抑制
 
#include <stdio.h> 

int f1(void)
{
    int a; 
    int *b; 

    printf("%p\n", &a); 
    b = &a; 
    *b = 100;    
    printf("%d\n", a);    
    printf("%p\n", &b);   
    printf("%p\n", b);    
    printf("%d\n", *b);   
 
    return 0;
}

int f2(void)
{
    int a2; 
    int *b2; 

    printf("%p\n", &a2); 
    b2 = &a2; 
    *b2 = 100;    
    printf("%d\n", a2);    
    printf("%p\n", &b2);   
    printf("%p\n", b2);    
    printf("%d\n", *b2);   
 
    return 0;
}
int main( void ) 
{    
    f1();

    f2();  
 
    return 0;
}
実行結果

コード:

G:\z18c\0123>c

G:\z18c\0123>rem コンパイル後リンク

G:\z18c\0123>cl /Fac1.asm /TC c1.c
Microsoft(R) C/C++ Optimizing Compiler Version 19.11.25508.2 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

c1.c
Microsoft (R) Incremental Linker Version 14.11.25508.2
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:c1.exe
c1.obj

G:\z18c\0123>rem 実行結果

G:\z18c\0123>c1.exe
008FF97C
100
008FF980
008FF97C
100
008FF97C
100
008FF980
008FF97C
100
G:\z18c\0123>
このようにローカル変数はメモリーを使いまわします。

返信

“C言語何でも質問掲示板” へ戻る