안녕하세요.


오늘도 ARM 명령어를 공부해 보겠습니다 ^^

QADD 명령어


QADD 명령어는 포화 산술 연산에 사용하는 명령어 입니다.


보통의 ARM 산술 연산 명령어에서는 32비트 정수값에 오버플로우가 발생하는 경우 이를 재대로 처리하지 못합니다.


예를들어,


   0x7FFFFFFF

+ 0x00000001

------------------------

  -0x80000000

이 됩니다.


그러므로 산술 연산을 처리하는 프로그램을 할 경우 32비트 정수에서 최대로 사용 가능한 값을 넘지 않도록 주의해야 합니다.


프로그램 두 가지를 만들어 포화 산술 연산 명령어가 어떨 경우 쓰이는지 생각해 보겠습니다 ^^

1. 프로그램



다음은 정수의 최대 값이 초과 되었을때 리턴되는 값을 확인하는 프로그램입니다.




#include <stdio.h>

int asm_qadd_ex( void );

asm(" \n\
.global asm_qadd_ex \n\
asm_qadd_ex: \n\
mov r1, #0x70000000 \n\
mov r2, #0x7FFFFFFF \n\
add r0, r1, r2 \n\
mov pc, lr \n\
");

int main ( void )
{
int qadd;

printf("\n+---------------------+\n");
printf("|ARM Instruction QADD|");
printf("\n+---------------------+\n\n");

qadd = asm_qadd_ex();

printf("smla value = 0x%08X\n\n", qadd);

printf("Program END\n\n");

return 0;
}


실행 화면을 보겠습니다 ^^


asm_qadd_ex1.PNG


이런 값이 왜 나왔을까요?


R2에는 32비트로 저장할 수 있는 최대 값이였습니다.


그렇게 때문에 R1과 R2를 더하면 더 큰 양수값 대신 음수값인 0xEFFFFFFF 값이 나오게 되며,


버퍼 오버플로우 플래그인 V 플래그가 세트(1) 됩니다 ^^


위와 같이 프로그램 한다면 버퍼 오버플로우가 발생했는지 판단하는 프로그램도 같이 해줘야 겠죠?


그래서 나온것이!


바로!! 오늘 배운 qadd 인것 입니다 ^^


qadd 명령을 이용하여 프로그램을 해보세요~~


간단하겠죠?


add 를 qadd 로만 바꺼주면 되겠습니다!!


mov r1, #0x70000000 \n\ 

mov r2, #0x7FFFFFFF  \n\ 

qadd r0, r1, r2 \n\ 

mov pc, lr \n\


위와 같이 하면 되겠죵!?

2. 프로그램 설명


QADD 명령은 ADD 명령어와 같은 방법을 더하는 명령어이지만,


결과 값을 포화 시키는데 필요한 명령어 입니다 ^^


특별히 프로그램 설명할 것이 있나용~?ㅎㅎ


오늘은 생략 하겠습니다!!


곰곰히 생각(?) 해보세요~


제가 앞서 쓴 ADD 명령어를 보시면서요~ 

3. 프로그램 실행화면


다음은 QADD 명령어를 이용한 프로그램의 실행 화면 입니다.


asm_qadd_ex2.PNG


결과적으로는 R0의 최대 값인 0x7FFFFFFF 가 리턴이 됨을 보실수 있습니다.


또한 포화 상태라는 것을 가리키는 Q(포화 플래그)비트 가 세트(1)되며, 외부에서 클리어(0)으로 해줄때 까지 세트(1)로 유지가 됩니다 ^^

앞으로?

 

다음 글에도 ARM 명령어중 하나를 선택하여 프로그램해 보겠습니다. ^^