2016-09-05 4 views
1

최근에 fp 번호가있는 작은 프로그램을 작성하고있었습니다. 먼저 내가 정렬 위치에 이중 FP 읽기 (SSE에 대한 지침)scanf에서 double이 아닌 float을 가져 오는 이유는 무엇입니까?

segment .data 
scanf_fmt: 
     db "%f%ld", 0 

    segment .bss 
    align 16, db 0 
x  resq 1  ; for double fp 
number resq 1  ; for integer 
    align 16, db 0 
res resq 1  ; for double fp 

lea rdi, [fmt] 
lea rsi, [x] 
lea rdx, [number] 
xor eax, eax ; number of fp values(edited from mov rax, 1 ,still looks the same) 
call scanf 

그런 다음 나는 두 번 이동 :

movsd xmm0, [x] 

가 그럼 난 디버깅 시작 : 내가 읽을 수는 scanf에 대한 1.6에 입력 . 라벨 x에서

100 movsd xmm0, [x] 
(gdb) p/f x 
$1 = 1.60000002 
(gdb) n 
(gdb) p $xmm0 
$2 = {v4_float = {1.600000002, 0, 0, 0}, v2_double = {5.2..., 0}, ... 

부동 소수점 값은 이동하지만 (내가 사용 movsd)하지 이중 플로트 (movss) 여기

일이야 무엇으로? scanf(3)에서

+2

전체 프로그램, 작성 방법, 실행 방법 및 실행시 입력 한 내용을 보여줘야합니다. 대신 디버거에 표시 될 것으로 예상되는 내용이 필요합니다. –

+0

'mov rax, 1'은 버그입니다. 정수 레지스터에 포인터를 두 개로 전달하고 xmm reg에 FP 인수를 0으로 지정합니다. –

+0

@RossRidge 빌드 :'yasm -f elf64 -g dwarf2 main.asm; gcc -o main main.o' 실행 :'./main' 다음과 같이 입력하십시오 :'1.6' '{v4_float = {smth, 0, 0, 0}, v2_double = {1.6, 0}, .. . –

답변

3

:

%f는 선택적으로 서명 부동 소수점 숫자를 일치; 다음 포인터는 float에 대한 포인터 여야합니다. 당신이 그것을 말처럼

그래서 scanf와, [x]에 32 비트 단 정밀도 float을 저장. 다음 32 비트는 0으로 남습니다.

다른 모든 것을 본 것은 명백한 결과입니다. 빠르게 man 페이지에서 "더블"을 검색하여 찾을 수 있습니다처럼 double에 대한


변환 지정자는, %lf입니다.

+0

scanf double 부동 소수점 숫자를 정확히 읽는 방법은 무엇입니까? 따라서 scanf는 4 바이트 단 정밀도 부동 소수점뿐만 아니라 IEEE 754에 따라 메모리 위치에 8 바이트 double을 배치합니다. 형식은 비슷하지만 float 앞에 4 바이트 (0 바이트)를 채우는 것만으로는 float을 두 번 사용할 수 없습니다. –

+2

은 정상적인 사람처럼 맨 페이지에서'double'을 검색합니다. C에서이 작업을 수행하는 것과 같습니다. –

+0

아, 분명히 mans ("double"을 읽으려면 "lf")를 읽을 필요가 있습니다. 이제 gdb의 xmm0이 예상대로 인쇄되었습니다. –