여치의 프로그래밍 강좌 #1

조회 수 30037 추천 수 363 2005.07.27 23:11:53
/*
과거 모 잡지에 연재했던 프로그래밍 강좌입니다.
퍼가실땐 사전에 동의를 얻으시기 바랍니다.
-유영천
*/

소프트웨어와 하드웨어

필자는  어릴 때 학교 컴퓨터부에서 컴퓨터를 배웠다. 정확히는 BASIC언어의 프로그래밍과 컴퓨터구조의 기본 등을 배웠다. 그 때가 87년도였다. BASIC프로그래밍을 배우고 싶어서 아니고 그 당시에 컴퓨터 가르쳐 달라 하면 늘 그런 식이었다. 뭐 그렇다고 배운걸 사용해서 충실하게 프로그램을 짤 수 있는가 하면 그렇지도 않았다. 그 당시엔 왜 그렇게 어렵게 느껴지던지...

대학교 1학년이 되었을 때, 내가 만든 그래픽 데이터만 가지고는 게임을, 아니 게임까진 안가더라도 화면에 뭔가 움직이게 할 수 없다는 그 짜증나는 현실을 벗어나야겠다고 마음 먹었다.
그리하여 서점에 달려가서 당시로선 꽤 생소했던 ‘DirectX로 게임 만들기’ 어쩌고 하는 책을 사다가, C/C++과 DirectX, Windows프로그래밍을 맨 땅에 헤딩하면서 독학하게 됐다. 그게 지금의 프로그래밍 인생의 첫 걸음이었다 생각한다. 밤을 새워가며 무대뽀 정신으로 정진한 끝에 석달 만에 첫 게임을 만들어냈고 1년이 되기 전에 그 당시로서는 약간이나마 신기해보였던 3D데모를 만들어서 모 기업에 처음으로 취직하게 된다. 나름대로 고속으로 학습해가며 소위 현업 프로그래머가 된 것이다.
여차저차 해서 지금의 회사에서 네트웍 프로그래밍을 하게 되었을 때, 그리고 멀티 스레드를 처음 사용하게 되었을때 그 때 깨달았다. 내가 얼마나 무지했는지를... 나름대로는 좀 한다고 생각했던 내 프로그래밍 실력이 아무것도 아니었음을 깨달았다. 컴퓨터의 기본에 대해서, OS의 기본에 대해서 도무지 아는게 없었던 것이다. 당장 몰라도 뭔가 돌아가는 프로그램을 짤 수 있었으니까 정작 필요한 순간이 올 때까지 깨닫지 못했었다.
무지함을 깨닫고 서점을 뒤져 나에게 필요한 책들을 찾았다. 이후 새벽까지 사무실에 남아 OS와 컴퓨터 구조에 대한 책들을 탐독하게 됐던 것이다. 그 때 무지함을 깨닫지 못했으면 아마 지금쯤 쓰레기 같은 코드나 생산해내며 동료들에게 욕이나 먹고 있을것이다.
많은 이들이 C나 그보다 더 쉬운 비주얼베이직으로 프로그래밍을 시작하곤 한다. 물론 프로그래밍 언어를 모르면 뭔가 만들어낼 수가 없다. 그러니까 프로그래밍을 하려면 언어를 익히는건 기본이다. 그러나 프로그래밍 언어보다도 더 기본은 컴퓨터가 어떻게 돌아가는지, 그 위에서 OS가 어떻게 돌아가는지 내가 만든 프로그램이 어떻게 돌아가는지 이걸 아는 것이다.
강좌같은 걸 하게 된다면 이 점을 꼭 강조하고 싶었다. 그리고 C언어로 화면에 ‘Hello World'를 출력하는 프로그램을 짜기 전에 간단하게라도 기본적인 메카니즘을 설명해두고 싶었다.
때문에 프로그램 코드나 Visual C++툴 설명같은건 하나도 없는 이런 글로 첫 회를 시작하게 된 것이다.


컴퓨터를 구성하는 요소

-소프트웨어
CD나 하드디스크 그리고 불과 몇 년 전까지만 해도 디스켓에 담겨있던 게임이나 유틸리티, 영상, 음악 자료들까지 소프트웨어라 할 수 있다.

-하드웨어
벌레같이 생긴 칩들이 붙어있는 장치들.컴퓨터 본체를 비롯한 주변기기들.
삼척동자도 다 아는 얘기니 굳이 더 이상 긴 설명은 필요없을 것이다.


하드웨어를 구성하는 3대 요소
-Memory
-Stack
-CPU


MEMORY
넓은 범위에서 디스크 장치를 비롯한 기타 보조 기억장치들도 메모리의 범주에 들어가지만 여기서 말하는 메모리는 RAM이다. 256MB니 512MB니 하면서 PC사양 말할 때 빠지지 않는 그 녀석 말이다.
메모리를 흔히 기억장치라고 한다. 그러나 일반인들에게는 쉽게 납득할 수 없는 해석이다. 도무지 얘가(컴퓨터가) 뭘 기억하고 있단 말인가? 하드디스크는 분명히 [기억]을 하고 있어 보인다.전원 끄고 몇 일 있다가 다시 켜도 있던 내용이 그대로 있으니까. 전원 끄면 메인 메모리에 있는건 싹 날아가 버리는데...
하지만 전원이 공급되는 동안은 기억하고 있는게 맞다. 실제적으로는 임시 기억 장소라 고 보는게 더 정확할 것이다. 기억장치 대신에 책상, 즉 작업공간이라고 생각해두자. 책상이 크면 그만큼 많은 것들을 올려놓고 작업할 수 있으니 빠르고 편하다. 책상이 손바닥만하다면 뭐 하나 하려고 하면 올렸다 내렸다 손은 바쁘게 움직이되 일 전체는 느려질 것이다.

메모리에 뭔가를 저장하고 다시 꺼내오려면..주소(Address)가 필요하다. 지하철역 락커에다 축구공을 보관했다가 꺼내오려면 공을 넣을때 몇 번 함인지는 봐둬야 하지 않겠는가? 이게 주소다. 메모리를 사용하려면 주소가 필요하다. 당장 주소를 어떻게 지정하고 사용하는지에 대해선 언급하지 않겠다. 이후에 C프로그래밍의 포인터를 다룰 때 이 개념이 와 닿질 않으면 고생한다. 메모리 하면 항상 따라다니는게 주소임을 유념하자.


I/O (Input / Output)
일단 cpu와 메모리가 연결만 되어있으면 최소한 프로그램 코드는 돌게 할 수 있다. 그러나 그게 무슨 의미가 있는가? 사람에게 결과를 보이지 않는 프로그램이라는 건 그다지 의미가 없다. I/O라는 것은 CPU입장에서의 입출력을 말한다. 사람의 뜻(조이스틱, 마우스, 키보드 등을 통해서 전달한다)을 CPU에 전달하고 CPU의 뜻(산술연산의 결과라든가... 아니면 여러분이 디스크에 저장하고 있던 이쁜 아가씨 사진이라든가 하는 데이터들)을 여러분에게 전달하기 위해서(일반적으로 모니터를 통해서)는 반드시 입출력이 필요한 것이다.
이런 것들이 I/O다. CPU입장에서 봤을 때 메모리에 쓰고 읽어오는 것 자체도 I/O지만 통상 I/O라고 하면 메모리를 제외한 주변 장치들과의 입출력을 뜻한다.
비디오 카드에 데이타를 전송해서 결과를 출력하고 키보드와 마우스로 입력을 받는 작업들이 I/O의 대표적인 예라 하겠다.


CPU
CPU(Central Processor Unit)은 중앙처리장치라고도 부르며 산술 연산 및 제어를 담당한다. 라고 교과서에 지긋지긋하게 나온다.
필자는 초등학교때 이런 저런 대회에 학교 대표로 나갈 기회가 있었는데 그때 이 내용을 처음 배웠다. 그 당시 PC의 생긴 모습이란게 본체와 키보드가 합쳐진, 그러니까 좀 많이 두꺼운 키보드였다. 요새 PC는 본체의 케이스를 열기도 편하고 열어서 안을 들여다 볼일도 자주 있는 편이지만 그 당시 그 두꺼운 키보드를 뜯는다는 것은 고장나서 A/S기사가 뜯는게 아니고선 있을 수 없는 일이었다.(뚜껑을 열고 확장슬롯에 주변장치를 꽂을 수 있었던 애플II pc도 있긴 했다.)
그러니  내 책상 위에 IBM PC호환 기종을 처음 올려놓던 89년도 이전까지 CPU라는걸 구경해 보질 못했다. CPU란 놈이 산술 연산 및 제어를 담당하는지 어쩌는지는 확실히 몰랐으나 초등학교 5학년 그 때 케이스를 열고 cpu를 처음 뽑아봤을 때, 확실한거 하나는 알게 됐다. CPU가 없으면 컴퓨터가 안돌아가더라 하는 것을 말이다.
여튼 CPU를 뽑으니 안돌아가더란 사실은 CPU가 굉장히 중요한 일을 한다는 것을 단적으로 증명해주는 것이다.
CPU가 제어를 한다 했다. 그럼 대체 뭘 제어하나? CPU밖에 연결된 모든 장치들, 메모리와 기타 주변기기들을 제어한다. 화면에 글자 하나를 찍는 것도 CPU가 비디오카드에 신호를 보내기 때문에 가능한 것이다. 이런 행위들을  I/O라 부른다고 위에서 얘기했다.
그럼 연산은? 연산이야 말 그대로 연산이다. 1+1=2. 이것이야말로 컴퓨터가 발명된 본연의 목적이었다. 지금은 별반 연산을 하지 않는다고 생각하는 이들도 있을지 모르겠다.(나는 계산기 프로그램을 거의 안쓴단 말이다! 라고 주장하면서...) 그러나 위에서 설명한 제어를 행하기 위해서도 내부적으로는 생각보다 많은 연산이 이루어진다. 그럼 뭘 연산하나? 뭘 연산시킬지는 프로그램짜는 놈 맘이다. 무엇을 어떻게 연산하게 할지 그 일련의 작업을 CPU가 알아먹게 나열해놓은것....그것이 프로그램, 또는 소프트웨어인 것이다. CPU를 부려먹을 이 프로그램 또는 소프트웨어는 어디 들어가냐고? 바로 메모리에 들어간다. CPU가 메모리로부터 읽어온다. 읽어다가...그대로 수행하는것이다.

hardware.jpg


그리고 관련된 장치 및  개념들

BUS
여기서 중요한 점을 떠올릴 수 있다. CPU와 메모리는 연결되어있다는 점이다. ‘당연한걸 가지고 대단한 걸 발견한 양 떠드는군’이라고 생각하며 돌을 집어드는 독자가 있는가? 조금만 참아보라.
CPU와 메모리는 무엇으로 연결되어있나? 당연히 전선으로 연결되어있다. 정확히는 PCB기판에 붙어있는 얇은 박막으로 연결되어있다. 이 놈들은 CPU의 어느 핀들과 연결되어있다. 이놈들..이놈이 아니고 이놈들...핀이 여러개고 선도 여러개다. CPU와 메모리를 연결하는 이 선들...버스다..물론 엄밀히 따져 딸랑 선만 놓고 버스라고 하진 않지만. CPU와 메모리 그리고 주변장치는 이런 선들로 연결되어있고 이를 버스라 한다. 데이터 버스 폭이 16비트네 32비트네 64비트네 하는데 대충 16비트면 데이터버스 선이 16개, 32비트면 32개 , 64비트면 64개라고 생각하면 된다. 물론 데이터버스만 가지고 신호를 주고 받을 순 없고 어드레스 버스도 같이 따라다닌다. 이쯤 되면 눈치 빠른 독자들은 ‘아 버스선이 32개면 32비트 CPU겠군!’이라고 생각할것이다. 아주 틀린 소린 아니지만 또 정답은 아니다.
인텔 펜티엄의 경우 32비트 CPU지만 외부 데이터 버스는 64비트다. 과거 인텔 8086 CPU또한 16비트 CPU였지만 외부 데이터버스는 8비트짜리였다.
흔히 말하는 몇비트 CPU다. 몇비트 PC다 하는 것은 CPU내부에서 처리하는 단위를 지칭한다. 내부에서 처리하는 단위라는것은...연산은 물론이요 제어에도 통용된다. 제어? 메모리를 억세스 하는것도 제어에 속한다. 메모리를 억세스 하려면 주소가 필요하다. 내부 처리 단위가 32비트라는 것은 주소도 32비트 단위로 처리한다는 것을 뜻한다..그럼 어드레스 버스도 32비트겠네..맞다. 어드레스선이 32비트라면 32비트 CPU라고 할 수 있다. 어드레드선이 64비트라면 64비트 CPU인것이다.


BIT
전구가 1개 있다. 불이 꺼져있을 때를 0, 켜져 있을 때를 1이라 하자. 그럼 전구 하나로는 0과 1 두 가지를 표현할 수 있다.  그럼 전구 두개로는 몇 가지 상태를 표현할 수 있나?
00 , 01, 10, 11 이렇게 네 가지를 표현할 수 있다.
전구 한개는 2진법의 한자리(0과 1)와 같다. 이것이 컴퓨터에서 말하는 BIT이다. 0과 1의 상태를 가지는 하나의 조각이 1비트이다. 당연히 전구 2개면 2비트이다.
N개의 비트가 나타낼 수 있는 경우의 수는 이다.
위에서 언급했던 버스의 데이터 선 한개 한개는 실제로 하나의 비트가 된다. 0과 1의 상태를 가질 수 있는 모든 것은 하나의 비트라 할 수 있다. 8비트 CPU는 8개의 비트로 구성된 상태를 가진다. 은 256이므로 최대 256가지, 자연수로는 0부터 255까지 정수로는 -128부터 127까지의 상태를 가진다.  

BYTE
8비트를 묶어서 1바이트라 부른다. 일반적으로 1바이트는 영문자 한 문자에 해당한다(ASCII코드 기준으로 1바이트는 영문자 한문자다. 아직은 프로그래밍할 때 UNICODE보단 ASCII코드를 많이 쓴다.)
현대 컴퓨터에서 사용하는 최소단위는 바이트이다. 메모리를 억세스할 때도 최소 단위는 바이트이고 표기할 때도 용량을 표현할 때도 바이트로 표기한다.

킬로, 메가, 기가, 테라 와 같은 용어를 많이 들어봤을 것이다.
산수에선 1000단위로 단위가 바뀌지만, 컴퓨터의 단위에선 1024즉 2의 10승이 될 때마다 상위 단위가 바뀐다.

1024Bytes == 1KBytes(킬로)
1024KBytes == 1MBytes(메가)
1024MBytes == 1GBytes(기가)
1024GBytes == 1TBytes(테라)

여러분이 일반적으로 사용하는 32Bits CPU를 장착한 PC는 최대 를 표현할 수 있다. 뭐야? 난 이보다 큰 숫자도 봤어..라고 발끈하는 독자가 있을지도 모르겠다. 물론 소프트웨어적으로 표현은 가능하지만 CPU내부에서 처리하는 단위로는 가 최대다. 대략 42억 정도 되는 숫자가 한계 표현 수치인 것이다
이와 관련된 여담을 하나 해보자.
필자가 C프로그래밍을 처음 시작했던 초딩 6학년때는 8088 CPU를 장착한 XT기종과 16비트 TurboC컴파일러를 사용했다. 베이직 프로그램을 짜던 버릇으로 1부터 100까지 합을 구하는 프로그램을 먼저 짰는데 제대로 결과가 나왔다. 5050이다. 1부터 1000까지 합은 500500이다. 그런데 500500이 나오지 않았다. 그 간단한 프로그램이 뭐가 잘못됐다고..아무리 뜯어봐도 코드는 문제가 없었다. 1부터 100까지 합 구하는 코드에서 100을 1000으로만 바꾸면 되는거니까 뭐 실수할 것도 없었다..
어디 물어 볼 이도 없고 고민하다가 거기서 그대로 손을 놨던 기억이 난다. 당시의 16비트 시스템에선 int형(정수형) 변수의 표현범위가 16비트, 즉-32768부터 32767까지 65536가지라는 사실을 몰랐다. 16비트 int형으로는 500500이라는 숫자를 때려죽여도 표현할 길이 없었던 것이다. 똑똑한 독자라면 그보다 큰 숫자는 어떻게 사용하냐고 반문할 것이다. CPU를 직접 제어하는 어셈블리 프로그래밍의 경우 프로그래머가 여러 개의 레지스터를 사용해서 더 큰 숫자를 사용할 수 있도록 짜면 된다. C같은 고급언어의 경우는 컴파일러가 이러한 코드를 생성해준다.당연히 코드가 느리고 복잡해진다.
요새의 CPU는 32비트로 42억 정도의 숫자를 표현할 수 있으므로 실제 프로그램을 짜면서 이런 문제로 고민할 일은 거의 없다. 42억이면 얼마 안되는 숫자같지만 0부터 42억까지 화면에 출력해보는 간단한 프로그램을 짜놓고 가만히 구경하고 있으면 억수 오래 걸린다는 것을 알 수 있다.실로 어마어마하게 큰 숫자로서 일반적인 프로그래밍에선 거의 다룰 일이 없다.

HEX(16진수)
인간은 실생활에서 10진수를 주로 사용하지만, 컴퓨터는 2진수를 사용한다. 기계적으로 두 가지의 상태만 표현할 수 있으므로 2진수 외에는 사용할 수 없다.(내부적으로). 10진수로 표현될때는 출력장치로 사람에게 보여질 때 뿐이다. 그러나 프로그래밍의 관점에서 컴퓨터를 사용할때는 여러 이유로 직접 각 자리수를 표현해야할 때가 많다.
10이라는 숫자 자체로는 별 의미가 없어 보이지만, 1010이란 2진수로는 엄청 큰 의미를 바로 알 수 있는 경우가 많다는 얘기다. 그렇다고 2진수 그대로 표현하자니 자릿수가 너무 많다. 출력하기도 힘들고 사람이 입력하기도 헷갈린다. 32비트면 0과 1을 32개나 주욱 깔아야되는데 대체 어디까지가 8비트(1바이트)인지 알기도 힘들다. 그런데 4비트, 8비트 이렇게 딱딱 끊어져 보이는 놀라운 숫자 표기법이 있었으니 그게 16진수다.
10진수로 4294967295라는 정신 사나운 숫자를 2진수로 표현하면 11111111111111111111111111111111이다. 대충 봐도 이런걸 프로그램짜면서 써넣기는 힘들어보인다. 16진수로는 0xFF FF FF FF. 매우 간결하다. 게다가 각 숫자,문자가 표현하는 한 단위가 4비트씩이므로 어느 자리가 얼마인지 알아보기도 쉽다.
이러한 이유로 하여 각종 에디터에서는 16진수를 많이 사용한다. 게임 크랙하는 사람들 사이에 HEX에디터 어쩌고 하는 것도 그러한 툴들이 내용을 16진수로 보여주기 때문이다.(보통 16진수와 ASCII코드 문자로 보여준다)


REGISTER
CPU안에도 메모리가 있다. 레지스터라고 부른다. CPU안의 각 상태를 저장하고 데이터 이동,연산의 기본이 된다. 간단하게 얘기해서 프로그래머가 짠 코드는 레지스터들을 제어하는 코드이다. 예를 들어 1+1을 구하는 프로그램을 짠다면..기계어와 1대1 대응되는 어셈블리 코드로 다음과 같다.

mov        eax,1                ; eax레지스터에 1을 넣는다.
mov        edx,1                ; edx레지스터에 1을 넣는다.
add        eax,edx                ; eax와 edx의 내용을 더한다. 더한값은 eax레지스터에 저장된다.
보면 알겠지만 연산에 있어선 레지스터를 사용하지 않고선 불가능하다. 인텔계 x86 cpu는 메모리->메모리 전송도 가능하지만 그 외 상당수 CPU는 데이터 이동에서도 레지스터를 거쳐야만 하지만

32비트 CPU라면 그 안에 가지고 있는 범용 레지스터는 모두 32비트짜리이다. 각 레지스터들은 한번에 32비트짜리 데이터만을 저장할 수 있다. 물론 메모리 어드레싱을 위한 특수한 레지스터나 SIMD(Single Instrunction Multiple Data)용 레지스터들은 사이즈가 제각각이다)

레지스터를 직접 제어하려면 어셈블리나 기계어 프로그래밍을 해야한다. 이 강좌는 C언어를 기본으로 하므로 레지스터를 직접 제어할 일은 거의 없을 것이다. 그러나 이러한 메카니즘을 알아둬야 디버깅을 그나마 좀 쉽게 할 수 있다. 또한 C에서도 중간중간 어셈블리 코드를 끼워넣어 사용할 수 있으므로 개념을 머릿속에 확실히 넣어두자.

CLOCK
CPU와같은 전자회로는 내부적으로 동기(Sync.)가 맞아야한다. 회로는 이전의 데이터값에 영향을 받아 작동하므로 이전상태를 [기억]하고 있어야하며 이전 상태와 현재 상태를 가르는 기준으로 클럭이라 부르는 사각파 전기신호를 사용한다.  파형의 한 주기가 한 클럭이고  한 주기가 바뀔때마다 새로운 상태(개념적으로.실제로 데이터는 아무것도 안바뀌었을수도있다)가 되는 것이다.
CPU를 움직이는 명령어는 한클럭(한주기)만에 완료되는 것도 있지만, 아닌것도 많다. 즉 회로구성이 이전 상태 (이전 주기)를 필요로 하는 명령은 여러개의 클럭을 필요로 하게 된다. 또는 메모리칩등 속도가 느린 장치를 억세스할때 속도를 맞추기 위해 대기해야하므로 여러개의 클럭을 소모하게 된다.
흔히 2.4GHz 펜티엄4네 어쩌고 하는 소릴 하는데 여기서 말하는 2.4GHz가 클럭 주파수를 뜻한다. 더 쉽게 말하면 클럭의 한 주기가 초당 24억번 클럭주기가 들어간단 얘기다. 모든 명령어가 1클럭에 끝나는 이상적인 시스템이 있다면 초당 24억개의 명령을 수행할 수 있다는 얘기가 된다.(물론 그런 시스템은 없다.) 명령어당 걸리는 클럭수가 같은 두 개의 CPU가 있다면 당연히 클럭주파수가 높은 쪽이 같은 시간에 더 많은 명령을 수행할 수 있다. 즉 더 빠르다 할 수 있다. 그러나 클럭 주파수가 높다고 꼭 빠른건 아니다. 평규적으로 명령어 처리에 10클
파일 첨부

여기에 파일을 끌어 놓거나 파일 첨부 버튼을 클릭하세요.

파일 크기 제한 : 0MB (허용 확장자 : *.*)

0개 첨부 됨 ( / )
List of Articles
번호 제목 글쓴이 날짜 조회 수
83 여치의 프로그래밍 강좌 #6 file [1] 여치 2005-07-27 29846
82 여치의 프로그래밍 강좌 #5 file 여치 2005-07-27 42032
81 여치의 프로그래밍 강좌 #4 file 여치 2005-07-27 39350
80 여치의 프로그래밍 강좌 #3 file 여치 2005-07-27 35348
79 여치의 프로그래밍 강좌 #2 file 여치 2005-07-27 31837
» 여치의 프로그래밍 강좌 #1 file 여치 2005-07-27 30037
77 지형도 BSP를 사용하시나요? [1] 초보 2005-07-06 26491
76 DirectX 입문용으로 적절한 책이 있을지요? [2] MiR 2005-03-01 41287
75 [re] DirectX 입문용으로 적절한 책이 있을지요? [1] 여치 2005-03-02 30297
74 BSP/Portal/PVS에 대한... guest 2005-02-18 24490
73 [re] BSP/Portal/PVS에 대한... file 여치 2005-02-19 23534
72 3D가속에 관한 질문 [3] 바하무트 2004-12-29 37321
71 [re] 3D가속에 관한 질문 여치 2004-12-29 27613
70 [질문] HeightMap의 퍼포먼스... [1] croove 2004-11-01 28868
69 [상담] 어떻게 해야할까요? . 2004-08-20 26046
68 [re] [상담] 어떻게 해야할까요? [1] 여치 2004-08-21 29021
67 [질문] 힙메모리 라이브러리에대해서. clever98 2004-08-08 32744
66 [re] [질문] 힙메모리 라이브러리에대해서. [1] 여치 2004-08-08 30295
65 [re] [질문] 단편화의 제거는 어떤식으로 하시나요? [1] 웰치스포도주스 2004-11-23 27815
64 개발 인력에 대한 질문 [1] 방문객 108 2004-07-20 23064



XE Login

天安門大屠殺 六四天安門事件 反右派鬥爭 大躍進政策 文化大革命 六四天安門事件 The Tiananmen Square protests of 1989 天安門大屠殺 The Tiananmen Square Massacre 反右派鬥爭 The Anti-Rightist Struggle 大躍進政策 The Great Leap Forward 文化大革命 The Great Proletarian Cultural Revolution 人權 Human Rights 民運 Democratization 自由 Freedom 獨立 Independence 多黨制 Multi-party system 民主 言論 思想 反共 反革命 抗議 運動 騷亂 暴亂 騷擾 擾亂 抗暴 平反 維權 示威游行 法輪功 Falun Dafa 李洪志 法輪大法 大法弟子 強制斷種 強制堕胎 民族淨化 人體實驗 胡耀邦 趙紫陽 魏京生 王丹 還政於民 和平演變 激流中國 北京之春 大紀元時報 九評論共産黨 獨裁 專制 壓制 統一 監視 鎮壓 迫害 侵略 掠奪 破壞 拷問 屠殺 肅清 活摘器官 障テ社會 誘拐 買賣人口 遊進 走私 毒品 賣淫 春畫 賭博 六合彩 台灣 臺灣 Taiwan Formosa 中華民國 Republic of China 西藏 土伯特 唐古特 Tibet 達償ワ喇嘛 Dalai Lama 新疆維吾爾自治區 The Xinjiang Uyghur Autonomous Region free tibet