본문 바로가기

전체43

1.2.7 기계어의 어셈블리어로 번역 RISC-V어셈블리어와 기계어의 관계 표 번역 과정 1단계 : 16진수의 2진수로의 변환 (기계어를 2진수로 쓰면 너무 길어지기 때문에 4비트를 한 글자만으로 표현할 수 있는 16진수를 쓴다) 예 : 00578833 = 0000 0000 0101 0111 1000 0011 0011 2단계 : 이진수를 해석하는 방식을 맨 오른쪽 7비트 (=opcode)로 결정 예 : 011 0011 = R-type 3단계 : 결정한 해석 방식에 맞게 해석 예 : (아래 사진) (참고용 : 아래는 모든 해석 방식) 2022. 3. 4.
1.2.6 어셈블리어로 긴 수치와 주소를 쓰는 법 32비트 크기의 상수를 만드는 법 RISC-V는 한 명령어당 최대 32비트까지만 쓸 수 있게 설계 되어있고 그 중 상수를 표현하는 파트인 immediate는 12비트까지만 쓸 수 있다 이것을 극복해서 32비트 꽉 채워서 상수를 만드는 방법은 두 이진수 문장을 합치는 것이다. 아래가 예시다. 목표 x19에 00000000000000000000000000000000 00000000001111010000010100000000 넣기 1단계 lui는 상수를 기존 11 ~ 0비트가 아니라 레지스터의 31~12비트에 넣는 함수이다 그리고, 넣을 0000 0000 0011 1101 0000은 십진수 976과 같아서 lui x19, 976를 쓴다. 따라서 현재 x19 = 000000000000000000000000000.. 2022. 3. 2.
1.2.5 어셈블리어로 문자와 문자열 사용해보기 문자 구현의 원리 컴퓨터가 레지스터로 문자를 표현하는 방식은 언어처럼 특정 십진수와 특정 문자가 같다고 약속으로 정해두고 그렇게 인식하도록 CPU를 설계하는 것이다. 그것에 대한 규약이 ASCII(American Standard Code for Information Inter-change) 문자열 구현의 원리 문자 데이터 모아서 문자열을 만드는데, 컴퓨터가 어디까지가 문자로 처리할 지를 결정하도록 하기 위해 문자열의 길이에 대한 정보도 같이 써야한다. 이때 쓰는 방식은 다음 3가지로 나뉜다. 1. 문자열의 맨 앞에 길이를 표시 (JAVA) 2. 구조체처럼 같이 사용되는 변수가 그 길이를 표현 하도록 하기 3. 마지막에 문자열의 끝을 표시하는 특수문자를 두기 (C) 어셈블리어로 문자열 복사 프로시저 구현 .. 2022. 2. 27.
Clean Code : 추상화 추상화 코드 블럭 내의 코드들을 추상화를 해야한다 왜냐하면 세부적인 건 변동할 확률이 높아서 추상적으로 먼저 안정적이게 틀을 잡아야한다. 그리고 프로그래머가 세부적인 것보단 핵심에 좀더 집중할 수 있게 해준다 예를들자면 아래 코드들과 같다 public interface Vehicle { double getFueltankCapacityInGallons(); double getGallonsOfGasoline(); } 위 코드를 아래와 같이 바꾼다 public interface Vehicle { double getPercenFuelRemaining(); } 아니면 이렇게도 가능하다 public class Point { public double x; public double y; } 위의 코드를 아래로 바꾼다 .. 2022. 1. 18.
1.2.4 어셈블리어로 프로시저 구현 프로시저 : 특정 업무 수행을 위한 절차들의 기술 함수 : 각 절차의 구현 (프로시저와 함수는 코드의 가독성과 재사용성을 높이는 추상화 방법 중 하나다) 인수 : 입력 겸, 데이터와 프로시저를 잇는 인터페이스 프로시저의 실행 과정 1. 프로시저에 인수 입력 2. 프로시저에 제어 넘기기 3. 프로시저는 필요한만큼 메모리를 가져가서 작업을 수행한다 4. 프로시저는 리턴 5. 사용한 프로시저를 원래 위치에 되돌려 놓기 이때 쓰이는 레지스터들의 역할 x0 : 0만 담음 x1 : 다음 실행될 명령어의 주소를 담음 x2 : 다른 레지스터들의 값을 보존 (=sp, stack pointer) x5~7 : 보존 X x8(=fp), x9 : 보존 O x10~17 : 인수용 x18~27 : 보존 O x28~31 : 보존 X.. 2022. 1. 18.
Clean Code : 주석2 정보를 제공하는 주석 때로는 기본적인 정보를 주석으로 제공하면 편리하다. 예를 들자면 반환할 값에 대한 설명이다 // kk:mm:ss EEE, MMM dd, yyyy 형식이다. Pattern timeMatcher = Pattern.compile( "\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*"); 이왕이면 시각과 날짜를 변환하는 클래스를 만들어 코드를 옮겨주면 더 깔끔해 질수 있긴하다. 의도를 설명하는 주석 때때로 주석은 이해를 돕는 수준이 아니라 의도 자체를 알려줄 수도 있다. 예를 들자면 함수가 기능을 수행할때 그것의 코드블럭의 코드가 어떻게 그 기능을 수행하게 되는지 불분명할때 알려줄 수 있다. 의도를 명료하게 밝히는 주석 인수나 반환값 자체를 명확하게 만들면 좋긴 하겠지만, .. 2022. 1. 12.
Clean Code : 주석 나쁜 코드는 주석을 달게 아니라 새로 짜라 일단 잘 달린 주석은 그 어떤 정보보다 유용하지만, 신중하지 못한 주석은 더 이해하기 어렵게 만든다. 오히려 주석은 달면 무조건 좋은게 아니라 절대 선이 아니라 필요악임을 명심해라. 코드만으로 대게 의도를 충분히 표현할 수 있고 그렇게 되면 주석은 전혀 필요가 없다. 주석은 단지 우리가 코드로 의도를 표현하는데에 '실패' 했을 때, 만회하기 위해 선택하는 차악일 뿐이다. 그런 이유도 있지만 좀더 큰 이유는, 코드는 시간이 지남에 따라 변화하고 진화하지만 주석은 언제나 코드를 따라가지 못한다. 시간이 지남에 따라 점점 더 코드와 괴리되서 주석이 무엇과 관련되있는 것인지 조차 알 수 없는 모호한 고아로 변하는 사례가 너무나도 많다. 심지어 부정확한 주석은 주석이 아.. 2022. 1. 12.
Clean Code : 함수 1. 작게 만들어라 이건 로버트 C. 마틴의 생각이다 그의 40여년간 경험상 작게 만드는게 좋다고 확신한다. 나도 동의한다. 왜냐하면 함수가 길 수록 기억해야 할 것과 집중해야 하는 요소가 많아 져서 이해하기 어려워진다. 또한 짧으면 함수들을 나열한 것처럼 작성이 되는데, 함수는 동사나 동사구를 이름으로 쓰기까지 해서 작성 결과가 마치 이야기 책을 써놓은 것처럼 작성이 되서 이해하기 매우 숩다 2~4 줄인게 좋다고한다 이것을 위해 if, while, for의 코드블록은 한 줄이여야한다. 그리고 대게 거기서는 함수를 호출한다 2. 함수는 한가지만 해야한다. 그런데 정확히 한가지를 한다는 것의 기준이 무엇인가? 리턴만 해야하는가? 조건문을 하나만 써야하는가? 답은 추상화 수준이 하나여야 한다. 세부적인 기능.. 2022. 1. 11.
1.2.3 어셈블리어 구현 RISC-V는 명령어의 길이가 32bit이다 또한 32bit 미만으로 쓸 경우엔 나머지 bit는 부호의 확장으로 채워 준다. 명령어의 각 부분을 필드라 부른다. RISC-V는 아래처럼 총 6개의 필드로 나뉜다. 이 방식을 R타입이라고한다 그런데 피연산자는 5비트라 최대 31까지만 표현이 가능한데 실제론 32이상의 값을 입력 받는 경우가 많아서 비트 수를 늘려야한다. 그런데 모든 명령어의 최대 길이를 동일 하게, 명령어 형식을 동일하게 라는 규칙도 지켜야되서 만들어진 또 다른 타입도 있다. ld x9, 64(x22) 같이 피연산자가 하나인 경우엔 I타입이라고 부르는 아래와 같이 쓴다 명령어 sd(store destination)를 쓸 땐 아래와 같이 S타입을 쓴다 여기선 12비트 수치값이 하위 5비트와 상.. 2022. 1. 7.
1.2.2 숫자 구현 이해를 위해, 이진수 문장만 저장 가능한 레지스터가 십진수 숫자인 11을 저장하는 것을 예시로 설명하겠다 레지스터는 64개의 트랜지스터로 2의 64제곱 경우의 수만큼 이진수 문장을 만들 수 있다 트랜지스터의 표기법은 배치된 순서대로 63, 62, 61 ... 0 이렇게 번호를 붙이고 나열한다. 그리고 모든 트랜지스터에 0을 넣는다. 이제 11을 중복된 지수가 없는 2의 제곱들의 합으로 표현한다. 그 결과 8 + 2 + 1 = 2^3 + 2^1 + 2^0 이제 각 항의 지수와 같은 숫자를 가진 표기 번호의 트랜지스터의 값을 1로 바꾼다 3210 (트랜지스터 표기번호) 그 결과 1011 (트랜지스터 내부 값)이 된다 이때의 모든 트랜지스터를 표현하자면 아래와 같다 이런 방식으로 0과 2^63 사이의 모든 수.. 2022. 1. 6.