사용 개념: 덧셈·뺄셈 명령의 ADD, SUB, NEG와 데이터 전송 명령의 MOV.
세 문제 모두 같은 데이터를 쓴다. 값은 모두 부호 있는 더블워드다.
.data
Rval SDWORD ?
Xval SDWORD 26
Yval SDWORD 30
Zval SDWORD 40
풀이 전략. 식을 손으로 계산할 때의 순서를 그대로 적는다. ① 괄호와 부호로 식을 덩어리로 나눈다 ② 덩어리마다 레지스터 하나를 정해 변수 값을 가져온다(변수 자체는 건드리지 않는다) ③ 그 레지스터에서 계산한다 ④ 덩어리끼리 합친다 ⑤ 결과를 Rval에 적는다. 명령의 받는 쪽이 계산 결과로 덮이므로, 변수를 받는 쪽에 두는 순간 그 변수는 바뀐다. 이것이 ②에서 레지스터로 가져오는 까닭이다1.
문제 p1
Rval = -Xval + (Yval - Zval)을 어셈블리로 옮기라.
풀이
- 덩어리 나누기:
-Xval과(Yval - Zval)두 덩어리를 더한다. - 첫 덩어리(EAX):
Xval을 가져와 부호를 바꾼다. - 둘째 덩어리(EBX):
Yval을 가져와Zval을 뺀다. - 합치기: EAX에 EBX를 더한다.
- 저장: EAX를
Rval에 적는다.
mov eax,Xval
neg eax ; EAX = -26
mov ebx,Yval
sub ebx,Zval ; EBX = -10
add eax,ebx
mov Rval,eax ; -36
검증: −26 + (30 − 40) = −36. Rval에 들어가는 비트는 FFFFFFDCh다.
변형. 같은 식을 레지스터 하나(EAX)만 써서 옮기라.
풀이
식을 먼저 바꾼다. −Xval + (Yval − Zval) = Yval − Zval − Xval이다. 왼쪽부터 차례로 빼면 덩어리가 하나라 레지스터도 하나면 된다.
mov eax,Yval
sub eax,Zval ; EAX = -10
sub eax,Xval ; EAX = -36
mov Rval,eax
문제 p2
Rval = Xval - (-Yval + Zval)을 어셈블리로 옮기라. Xval, Yval, Zval이 바뀌면 안 된다.
풀이
- 덩어리 나누기:
Xval에서 괄호 덩어리(-Yval + Zval)을 뺀다. 빼는 쪽을 먼저 만들어 둔다. - 괄호 덩어리(EBX):
Yval을 가져와 부호를 바꾸고Zval을 더한다. - 앞 덩어리(EAX):
Xval을 가져온다. - 합치기: EAX에서 EBX를 뺀다.
- 저장.
mov ebx,Yval
neg ebx ; EBX = -30
add ebx,Zval ; EBX = 10
mov eax,Xval
sub eax,ebx ; EAX = 16
mov Rval,eax
검증: 26 − (−30 + 40) = 16.
흔한 오답: 첫 줄을 neg Yval로 시작한다. Rval은 똑같이 16이 되지만 Yval이 −30으로 바뀌어 문제의 조건을 어긴다.
문제 p3
Rval = (Xval - Yval) + (-Zval + 10)을 어셈블리로 옮기라. 변수는 바뀌면 안 된다1.
풀이
- 덩어리 나누기:
(Xval - Yval)과(-Zval + 10). - 첫 덩어리(EAX):
Xval에서Yval을 뺀다. - 둘째 덩어리(EBX):
Zval의 부호를 바꾸고 10을 더한다. - 합치기와 저장.
mov eax,Xval
sub eax,Yval ; EAX = -4
mov ebx,Zval
neg ebx ; EBX = -40
add ebx,10 ; EBX = -30
add eax,ebx ; EAX = -34
mov Rval,eax
검증: (26 − 30) + (−40 + 10) = −34.
변형. NEG를 쓰지 않고 EAX 하나로 옮기라.
풀이
괄호를 풀면 Xval − Yval − Zval + 10이다.
mov eax,Xval
sub eax,Yval
sub eax,Zval
add eax,10 ; EAX = -34
mov Rval,eax
부호를 바꿔 더하는 것은 그냥 빼는 것과 같다. 식을 먼저 정리하면 명령 수가 준다.