2016. 4. 13. 14:39 devel/man & example
arm assembly byte swap 예제 분석
arm 어셈블리 코드 선행 지식
대충 아는 분들은 아래로 죽 넘겨버리면 ok
c code
val = *addr;
gcc inline assembly
asm (
"ldr %0, [%1]"
: "=r"(val)
: "r" (addr)
);
':'이게 뭘까?
: output operand list(register to memory)
: input operand list(memory to register)
: clobber list(temporary variables, 컴파일러가 맘대로 못 쓰게 할 수 있음, 생략가능)
%0, %1, %2 .... output 부터 시작해 input에 나열된 변수 순서 대로 번호가 할당된다
예를 들어
: "=d (res)", "=&c" (d0), "=&D" (d1), "=&a" (d2) 이런게 가능
Constraints(info gcc 해서 ::Constraints 로 확인 가능)
: "0"(val) - src랑 dst를 같은 register쓰도록 강제(input, output)
0~9 등등 가능 아마도 %0을 같이 쓴다 이런 의미일듯
= output only variables(write only)
r register
등등 많다
Operand 2(Flexible second operand)
예제
mov r0, r1, lsl #3
r0 = r1<<3;
바이트 스왑 어셈블리 코드
0x12345678 -> 0x78563412
unsigned long ByteSwap(unsigned long val)
{
asm volatile (
"eor r3, %1, %1, ror #16 \n\t"
"bic r3, r3, #0x00FF0000 \n\t"
"mov %0, %1, ror #8 \n\t"
"eor %0, %0, r3, lsr #8 \n\t"
: "=r" (val)
: "0"(val)
: "r3"
);
return val;
}
%0 -> 함수 인자 val변수 (ldr r0, &val 대충 이런 느낌)
%1 -> %0과 동일
eor r3, %1, %1, ror #16
r3 = 12345678 ^ 56781234
= 444C444C
bic r3, r3, #0x00FF0000
r3 = r3 & 0xFF00FFFF
r3 = 444C444C & 0xFF00FFFF
= 4400444C
mov %0, %1, ror #8
%0 = 78123456
eor %0, %0, r3, lsr #8
%0 = %0 ^ (r3 >> 8)
= 78123456 ^ 00440044
= 78563412
이게 가능한 이유?
XOR의 특징 : a ^ b = c -> c ^ b = a
일단 byte swap의 규칙을 찾아보자
0x1234ABCD -> 0xCDAB3412
34랑 CD는 ror 8회 하면 된다
AB랑 12는 rol 8회 하면 된다
걍 ror 8회 하고 0xFF00FF00 이랑
rol 8회 하고 0x00FF00FF랑 or 하면 안되나요?
-> operand 2 에 constant 제약 때문에 안될듯? 아닌데 제약 범위 이내던데???
처음 eor 코드에서 일종의 백업을 한다 이제 r3는 원본인 %1과 ^를 하면 언제든지 ror 16회 된 데이터를 뽑아올 수 있다
bic(not and)를 사용해 체를 걸러낸다 왜 굳이 not을 하고 and를 해야했을까?
이제 FF00FFFF 에서 00 부분을 제외했기 때문에 ror 16회 한 56781234에서 56xx1234만 복원이 가능하다
FF00FF00 혹은 00FF00FF 형태로 만든 것과 ror 8 혹은 rol 8 한 값과
으메 모르겠다........
기타 추천 링크
http://xenostudy.tistory.com/206
'devel > man & example' 카테고리의 다른 글
gcc inline assembly (0) | 2016.08.11 |
---|---|
arm stm32f4xx software interrupt handler 만들기 (0) | 2016.08.09 |
dev file (0) | 2015.08.04 |
ioctl (0) | 2012.07.26 |
const (0) | 2012.07.21 |