Я собирал несколько простых программ в ассемблер из C ++ и Fortran, чтобы попытаться получить более высокую оценку компьютерной архитектуры.Я написал очень простую программу как на C ++, так и на Фортране, чтобы произвести вывод и затем вернуть.Я не понимаю, почему компилятор Фортрана (gfortran) создает сборку, которая создает такой большой кадр стека по сравнению с C ++.
f_subroutines.f
PROGRAM F_SUBROUTINES
CALL SAY_HELLO
CALL SAY_GOODBYE
END
SUBROUTINE SAY_HELLO
PRINT '(A6)', "Hello."
END
INTEGER*4 FUNCTION GET_MY_NUMBER()
GET_MY_NUMBER = 3
END
SUBROUTINE SAY_GOODBYE
INTEGER :: GET_MY_NUMBER
PRINT '(A18, I1, A19)',
1 "Here's my number: ", GET_MY_NUMBER(), ". Call me. Goodbye!"
END
cpp_subroutines.cpp
#include <cstdio>
void say_hello()
{
std::printf("Hello.\n");
}
int get_my_number()
{
return 3;
}
void say_goodbye()
{
std::printf("Here's my number: %d. Call me. Goodbye!\n", get_my_number());
}
int main()
{
say_hello();
say_goodbye();
return 0;
}
Makefile
CPPFLAGS=-O0
all: cpp_subroutines cpp_subroutines.s f_subroutines f_subroutines.s
cpp_subroutines: cpp_subroutines.o
$(CXX) $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
cpp_subroutines.s:
$(CXX) $(CPPFLAGS) -S cpp_subroutines.cpp
f_subroutines: f_subroutines.o
$(FC) -o $@ $^ $(LDFLAGS)
f_subroutines.s:
$(FC) -S f_subroutines.f
.PHONY: clean
clean:
$(RM) cpp_subroutines cpp_subroutines.o cpp_subroutines.s \
f_subroutines f_subroutines.o f_subroutines.s
cpp_subroutines.s: say_hello
_Z9say_hellov:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
f_subroutines.s: say_hello
say_hello_:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $480, %rsp
movq $.LC0, -472(%rbp)
movl $8, -464(%rbp)
movq $.LC4, -408(%rbp)
movl $4, -400(%rbp)
movl $4096, -480(%rbp)
movl $6, -476(%rbp)
leaq -480(%rbp), %rax
movq %rax, %rdi
call _gfortran_st_write
leaq -480(%rbp), %rax
movl $6, %edx
movl $.LC5, %esi
movq %rax, %rdi
call _gfortran_transfer_character_write
leaq -480(%rbp), %rax
movq %rax, %rdi
call _gfortran_st_write_done
nop
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
Я используюgfortran и gcc версии 5.4.0.
Я не совсем уверен, что здесь делает сборка Фортрана:
subq $480, %rsp
movq $.LC0, -472(%rbp)
movl $8, -464(%rbp)
movq $.LC4, -408(%rbp)
movl $4, -400(%rbp)
movl $4096, -480(%rbp)
movl $6, -476(%rbp)
leaq -480(%rbp), %rax
Кажется, для этого кадра стека используется 480 байт и
- Имя исходного файла (.LC0) 8 байтов снизу
- Значение 13 16 байтов снизу
- Спецификатор формата '(A6)'(.LC4) 64 байта снизу
- Значение 4 80 байтов снизу
- Значение 4096 (размер страницы?) Внизу
- Значение 6 4байтов снизу.
Я очень доволен выводом компиляции C ++, но мне хотелось бы знать why
- Компиляция Fortran создает такой большой кадр стека.
- Для чего существуют значения $ 8, $ 4, $ 4096 и $ 6.