《컴퓨터 시스템을 깊이 이해하다》 제2장.
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
이 문제에서 우리는 깨우침을 얻었다.
부점 연산을 매우 조심스럽게 사용해야 한다. 왜냐하면 부점 연산의 범위와 정밀도가 유한하고 부점 연산은 일반적인 산술 성질, 예를 들어 결합성을 준수하지 않기 때문이다.
미완성
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Ubuntu 22.04에 캐디 설치 - HostnExtra이 기사에서는 Ubuntu 22.04에 Caddy를 설치하는 방법을 설명합니다. 이 문서는 설치 프로세스를 안내하고 웹 사이트를 호스팅합니다. Caddy 웹 서버는 Go로 작성된 오픈 소스 웹 서버입니다. Ubunt...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.