《컴퓨터 시스템을 깊이 이해하다》 제2장.

3141 단어 ubuntuBloggccOS

1. 볼 대수와 고리
^(이 또는)의 링 속성을 이용하여 변수의 교환을 실현한다.
void inplace_swap(int *x, int *y){
      *x = *x ^ *y;
      *y = *x ^ *y;
      *x = *x ^ *y;
}

위의 이 절차와 같이 보아하니 왔다 갔다 하는 똑같은 연산이고 심지어 운산수조차도 같다.그러나 이렇게 세 줄 코드는 x와 y가 가리키는 데이터 값을 교환하는 효과에 이르렀다.
이 프로그램의 구체적인 과정을 간단히 분석해 봅시다.
단계
*x
*y
처음
a
b
첫걸음
a^b
b
두 번째 단계
a^b
a^b^b=a^0=a
세 번째 단계
a^b^a=a^a^b=0^b=b
a
 
 
 
 
 
 
 
 
 
좋아. 이렇게 보면 이 프로그램은 이미지 셋으로 보면 공간을 절약한 것 같지만, 코딩 등 밑바닥 실현으로 볼 때 어떠한 성능상의 장점도 없다.다음은 이 코드의 어셈블리 코드를 살펴보겠습니다.
 
어셈블리 코드 쓰기
.file "inplace_swap.c"
.text
.globl inplace_swap
.type inplace_swap, @function
inplace_swap:
pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl (%eax), %edx movl 12(%ebp), %eax movl (%eax), %eax xorl %eax, %edx movl 8(%ebp), %eax movl %edx, (%eax) movl 8(%ebp), %eax movl (%eax), %edx movl 12(%ebp), %eax movl (%eax), %eax xorl %eax, %edx movl 12(%ebp), %eax movl %edx, (%eax) movl 8(%ebp), %eax movl (%eax), %edx movl 12(%ebp), %eax movl (%eax), %eax xorl %eax, %edx movl 8(%ebp), %eax movl %edx, (%eax) popl %ebp ret
.size inplace_swap, .-inplace_swap
.globl swap
.type swap, @function
swap:
pushl %ebp movl %esp, %ebp subl $16, %esp movl 8(%ebp), %eax movl (%eax), %edx movl -4(%ebp), %eax movl %edx, (%eax) movl 12(%ebp), %eax movl (%eax), %edx movl 8(%ebp), %eax movl %edx, (%eax) movl -4(%ebp), %eax movl (%eax), %edx movl 12(%ebp), %eax movl %edx, (%eax) leave ret
.size swap, .-swap
.section .rodata
.LC0:
.string "Old: x=%d,y=%d"
.LC1:
.string "New: x=%d,y=%d"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl $1, -8(%ebp)
movl $2, -12(%ebp)
movl -12(%ebp), %eax
movl %eax, 8(%esp)
movl -8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl -12(%ebp), %eax
movl -8(%ebp), %edx
movl %eax, 4(%esp)
movl %edx, (%esp)
call inplace_swap
movl -12(%ebp), %eax
movl %eax, 8(%esp)
movl -8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC1, (%esp)
call printf
movl $0, %eax
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu1)"
.section .note.GNU-stack,"",@progbits
 
이 문제에서 우리는 깨우침을 얻었다.
  • 분석 프로그램의 성능은 원본 프로그램을 통해 간단하게 판단할 수 없기 때문에 어셈블리 인코딩, 심지어 OS 하드웨어와 관련된 명령 집행 상황을 깊이 있게 살펴야 한다
  • 수학의 아름다움은 어디에나 있다. 상상할 수 없는 것이 수학에서 대수환의 성질을 통해 쉽게 풀린다
  • 프로그램의 분석에 대해 논리가 명확하지 않은 것을 발견하면 표 등 도구를 빌려 한 걸음 한 걸음 조용히 분석해야 한다
  • Gedit를 구성하여 QR코드 강조http://qianjigui.iteye.com/blog/248085
  • 2. 부동점 연산의 부정확성
    부점 연산을 매우 조심스럽게 사용해야 한다. 왜냐하면 부점 연산의 범위와 정밀도가 유한하고 부점 연산은 일반적인 산술 성질, 예를 들어 결합성을 준수하지 않기 때문이다.
     
    미완성
     

    좋은 웹페이지 즐겨찾기