프로그래머는 변수와 명령어의 주소를 자주 더하고 뺀다. 그래서 16진 계산은 어셈블리어에서 꼭 익혀야 할 기술이다. 여기에 2의 보수와 글자 코드를 읽는 연습을 더해 모았다. 답을 펼치기 전에 종이에 먼저 써 본다.
p1 · 16진 덧셈
6A + 4B를 16진수로 계산하라.
사용 개념: 진법과 자릿수
풀이 전략: 10진 덧셈과 똑같이 오른쪽 자리부터 더한다. 다른 점은 올림이 생기는 기준이 10이 아니라 16이라는 것뿐이다. 한 자리의 합을 16으로 나눠, 몫은 왼쪽으로 올리고 나머지를 그 자리에 쓴다.
풀이
- 아래 자리 더하기: A + B = 10 + 11 = 21.
- 16으로 나누기: 21 ÷ 16 = 1, 나머지 5. 5를 쓰고 1을 올린다.
- 윗자리 더하기: 6 + 4 + 올림 1 = 11 = B. 16보다 작으니 올림이 없다.
- 답:
B5. - 확인: 10진수로 106 + 75 = 181 = 11 × 16 + 5.
변형 문제
- (가)
28 + 58(나)7C + 39(다)1A2B + 0F9E(라) 변수var1의 주소가00400020이고var1이4Ah바이트를 차지한다. 바로 다음 변수의 주소는?
답
(가) 80. 8 + 8 = 16이라 0을 쓰고 1을 올린다. 2 + 5 + 1 = 8. (나) B5. C + 9 = 21 → 5, 올림 1. 7 + 3 + 1 = B. (다) 29C9. B + E = 25 → 9, 올림 1. 2 + 9 + 1 = 12 → C. A + F = 25 → 9, 올림 1. 1 + 0 + 1 = 2. (라) 0040006A.
p2 · 16진 뺄셈과 변수의 크기
var1의 주소는 00400020이다. var1 바로 다음 변수의 주소는 0040006A다. var1은 몇 바이트를 차지하는가?
사용 개념: 진법과 자릿수
풀이 전략: 변수가 차지하는 바이트 수는 다음 변수의 주소에서 자기 주소를 뺀 값이다. 앞쪽 글자가 같으면 다른 부분만 빼면 된다. 한 자리에서 모자라면 왼쪽 자리에서 1을 빌려 오고, 빌려 온 1은 16으로 친다.
풀이
- 식 세우기:
0040006A − 00400020. 앞의004000이 같으므로6A − 20만 계산한다. - 아래 자리 빼기: A − 0 = A.
- 윗자리 빼기: 6 − 2 = 4. 빌려 올 일이 없다.
- 답:
4Ah바이트. 10진수로 4 × 16 + 10 = 74바이트.
변형 문제
- (가)
75 − 47(나)C6 − A2(다)0100 − 001C(라) 32비트 정수 배열의 시작 주소가00402000, 배열 바로 다음 변수의 주소가00402030이다. 배열에 정수가 몇 개 들어 있는가?
답
(가) 2E. 5에서 7을 못 빼므로 16을 빌려 16 + 5 = 21, 21 − 7 = 14 = E. 윗자리는 7 − 1 − 4 = 2. (나) 24. 빌려 올 일이 없다. (다) 00E4. 0 − C는 모자라므로 빌려 16 − 12 = 4. 다음 자리는 0 − 1(빌려준 것) − 1이 모자라므로 또 빌려 16 − 2 = 14 = E. 그 윗자리는 1 − 1 = 0. (라) 30h = 48바이트. 정수 하나가 4바이트이므로 12개.
p3 · 정해진 비트 수에 담기는 가장 큰 수
(가) 20비트에 담을 수 있는 가장 큰 부호 없는 정수는? (나) 20비트에 담을 수 있는 가장 큰 양수는(맨 윗비트를 부호로 쓸 때)?
사용 개념: 진법과 자릿수, 정수의 2진 표현과 2의 보수
풀이 전략: \(N\)비트로 만들 수 있는 줄은 \(2^N\)가지다. 부호 없이 쓰면 0부터 \(2^N - 1\)까지다. 맨 윗비트를 부호에 쓰면 양수 쪽에 남는 비트가 \(N - 1\)개라서 \(2^{N-1} - 1\)까지다.
풀이
- (가) 가짓수 세기: \(2^{20} = 1{,}048{,}576\)가지.
- (가) 0을 빼기: 0부터 세므로 가장 큰 수는 \(2^{20} - 1 = 1{,}048{,}575\). 16진수로
FFFFF(1이 20개). - (나) 부호 비트 떼기: 남은 비트는 19개. 가장 큰 양수는 \(2^{19} - 1 = 524{,}287\). 16진수로
7FFFF.
변형 문제
- (가) 12비트의 가장 큰 부호 없는 정수와 가장 큰 양수는? (나) 부호 있는 16비트(word)의 가장 작은 수와 가장 큰 수는?
답
(가) \(2^{12} - 1 = 4{,}095\)와 \(2^{11} - 1 = 2{,}047\). (나) −32,768과 +32,767.
p4 · 2진 뺄셈을 덧셈으로
2진수 1001에서 0101을 빼라. 4비트로 계산한다.
사용 개념: 정수의 2진 표현과 2의 보수
풀이 전략: \(A - B\)는 \(A + (-B)\)다. \(-B\)는 \(B\)의 2의 보수, 곧 비트를 모두 뒤집고 1을 더한 것이다. 그러면 뺄셈이 덧셈이 된다. 맨 윗자리 밖으로 나가는 올림은 버린다.
풀이
- 빼는 수 뒤집기:
0101→1010. - 1 더하기:
1010 + 1 = 1011. 이것이 −5다. - 더하기:
1001 + 1011 = 1 0100. - 넘친 올림 버리기: 4비트만 남기면
0100. - 확인: 부호 없는 수로 읽으면 9 − 5 = 4 =
0100.
1001을 부호 있는 4비트 수로 읽으면 −7이고, −7 − 5 = −12는 4비트의 범위(−8~7) 밖이다. 비트 계산은 같지만 결과 0100을 4라고 읽으면 틀린다. 어느 약속으로 읽는지에 따라 답이 맞는지가 달라진다1.
변형 문제
- (가) 8비트로
00001100 − 00000011(나) 4비트로1100 − 0110
답
(가) 00000011의 2의 보수는 11111101. 00001100 + 11111101 = 1 00001001 → 00001001(12 − 3 = 9). (나) 0110의 2의 보수는 1010. 1100 + 1010 = 1 0110 → 0110(부호 없이 12 − 6 = 6).
p5 · 부호 있는 수 다섯 가지 바꾸기
부호 있는 수를 다룰 때 할 줄 알아야 하는 다섯 가지다.
(가) 16진수 6A3D의 2의 보수를 구하라(16비트). (나) 부호 있는 2진수 11110000을 10진수로. (다) 10진수 −43을 8비트 2진수로. (라) −43을 16진수로. (마) 부호 있는 8비트 16진수 8A, C5, A2, 9D를 10진수로.
사용 개념: 정수의 2진 표현과 2의 보수
풀이 전략: 음수를 읽을 때는 “2의 보수를 구해 크기를 알아낸 뒤 − 부호를 붙인다”. 음수를 적을 때는 “양수를 적고 2의 보수를 구한다”. 16진수에서 비트를 뒤집는 것은 글자마다 15(F)에서 빼는 것과 같다. 맨 윗글자가 8 이상이면 맨 윗비트가 1이라 음수다.
풀이
- (가) 글자마다 F에서 빼기: F − 6 = 9, F − A = 5, F − 3 = C, F − D = 2 →
95C2. 1 더하기:95C3. - (나) 맨 윗비트 보기: 1이므로 음수. 2의 보수:
00001111 + 1 = 00010000= 16. 부호 붙이기: −16. - (다) 양수 적기: 43 =
00101011. 뒤집기:11010100. 1 더하기:11010101. - (라) 네 비트씩 끊기:
1101 0101→D5. - (마) 맨 윗글자 보기: 8, C, A, 9는 모두 7보다 크므로 음수. 2의 보수:
8A→75 + 1 = 76h= 118 → −118.C5→3B= 59 → −59.A2→5E= 94 → −94.9D→63= 99 → −99.
변형 문제
- (가) 16비트
00FF의 2의 보수와 그 값 (나) −100을 8비트 16진수로 (다) 부호 있는 16비트FFFF와8000의 값
답
(가) FF00 + 1 = FF01, 값은 −255. (나) 100 = 64h, 뒤집으면 9B, 1을 더해 9C. (다) −1과 −32,768.
p6 · 16진수로 적힌 글자 읽기
54 68 65 20 45 6E 64는 무엇을 나타내는가?
사용 개념: 부호와 부호화
풀이 전략: 두 글자씩 끊긴 16진수가 20~7E 범위에 몰려 있으면 ASCII 글자일 가능성이 크다. 외워 둘 기준은 셋이다. 41h가 대문자 A, 61h가 소문자 a, 20h가 빈칸이다. 나머지는 거기서부터 센다.
풀이
- 기준 잡기:
41h= A,61h= a,20h= 빈칸. - 한 바이트씩 세기:
54=41 + 13h→ A에서 19번째 뒤 = T.68=61 + 7→ h.65→ e.20→ 빈칸.45→ E.6E=61 + Dh→ n.64→ d. - 답: “The End”.
변형 문제
- (가)
42 69 6E 61 72 79는 무슨 낱말인가? (나) “Hi!”를 16진수 바이트로 적어라(!는21h).
답
(가) “Binary”. (나) 48 69 21.
-
p5 (가)의
6A3D는 교재 Irvine, Assembly Language for x86 Processors 7판, 1.3절의 예다. 답은 모두 문제 코드로 확인했다. ↩