2008-12-07 17 views
7

मुझे 32 बिट (हेक्साडेसिमल) शब्द 0xaabbccdd मिला है और उसे 2. और 3. बाइट स्वैप करना है। अंत में यह 0xaaccbbddएआरएम असेंबली में बाइट मास्क कैसे करें?

मैं दूसरे और तीसरे बाइट को पहली बार आर 1 और आर 2 रजिस्टर करने के लिए उन्हें लोड करने के लिए "मुखौटा" कैसे कर सकता हूं और उन्हें स्वैप कर सकता हूं .. मुझे यह भी पता है कि मुझे साथ काम करना है lsl और lsr आदेश लेकिन पता नहीं कैसे शुरू करें।

मेरी बुरी अंग्रेजी के लिए खेद है। कोई भी मेरी मदद कर सकता है!

संबंध है, सेबस्टियन

उत्तर

6

क्योंकि आप आसानी से 32 बिट स्थिरांक उपयोग नहीं कर सकते एआरएम विधानसभा में कोई सरल कार्य नहीं है यही कारण है कि। आपको अपने सभी परिचालनों को तोड़ना होगा जो प्रत्येक 8 बिट स्थिरांक का उपयोग करने के लिए बाइट्स को मुखौटा करते हैं (इन स्थिरांकों को भी घुमाया जा सकता है)।

आप एंड्रॉइड का उपयोग करके बाइट 2 और 3 को मुखौटा करते हैं और बाद में शिफ्ट करते हैं। एआरएम-असेंबलर में आपके पास अधिकतर निर्देशों के साथ एक शिफ्ट मुफ्त है, इसलिए शिफ्ट-इन-पोजीशन और अन्य बिट्स के साथ विलय अक्सर एक ही निर्देश होने का अंत होता है।

यहाँ कुछ अपरीक्षित कोड है कि मध्यम बाइट स्वैप करता है (ARMv4, नहीं अंगूठे के अनुदेश सेट) है:

 .text 

swap_v4: 
     AND  R2, R0, #0x00ff0000  @ R2=0x00BB0000 get byte 2 
     AND  R3, R0, #0x0000ff00  @ R3=0x0000CC00 get byte 1 
     BIC  R0, R0, #0x00ff0000  @ R0=0xAA00CCDD clear byte 2 
     BIC  R0, R0, #0x0000ff00  @ R0=0xAA0000DD clear byte 1 
     ORR  R0, R2, LSR #8   @ R0=0xAA00BBDD merge and shift byte 2 
     ORR  R0, R3, LSL #8   @ R0=0xAACCBBDD merge and shift byte 1 
     B  LR 

लाइन द्वारा लाइन का अनुवाद है कि निम्नलिखित सी कोड में:

int swap (int R0) 
{ 
    int R2,R3; 
    R2 = R0 & 0x00ff0000; 
    R3 = R0 & 0x0000ff00; 
    R0 = R0 & 0xff00ffff; 
    R0 = R0 & 0xffff00ff; 
    R0 |= (R2>>8); 
    R0 |= (R3<<8); 
    return R0; 
} 

आप देखेंगे - इस तरह के एक साधारण कार्य के लिए कई लाइनें। यहां तक ​​कि एआरएमवी 6 आर्किटेक्चर भी बहुत मदद करता है।


संपादित करें: ARMv6 संस्करण (भी अपरीक्षित, लेकिन दो निर्देश कम)

swap_v6: 
     @ bits in R0: aabbccdd 
     ROR  R0, R0, #8    @ r0 = ddaabbcc 
     REV  R1, R0     @ r1 = ccbbaadd 
     PKHTB R0, R0, R1    @ r0 = ddaaccbb 
     ROR  R0, R0, #24    @ r0 = aaccbbdd 
     BX  LR 
+0

उह कर देगा, है 32-बिट स्थिरांक का उपयोग कर, पहले उदाहरण में है कि नहीं? भ्रामक। – unwind

+1

हां, ये 32 बिट स्थिरांक हैं, लेकिन यदि आप नज़दीक देखते हैं तो उनके पास केवल 8 लगातार बिट्स हैं जो उनके स्थिरांक में उपयोग किए जाते हैं। एआरएम 8 बिट्स कर सकता है, लेकिन इनकी स्थिति आसानी से उस स्थान पर घुमाया जा सकता है जहां आप चाहते हैं। असेंबलर आपके लिए स्थिरांक को एन्कोड करने के लिए पर्याप्त स्मार्ट है। –

+2

किसी भी * यहां तक ​​कि * आप चाहते हैं; 0x1fe उदाहरण के लिए तत्काल तत्काल नहीं है, लेकिन 0x3fc है। –

0

तुम बस संकेत का उपयोग दो बाइट्स

static union { 
BYTE BBuf[4]; 
WORD WWBuf[2]; 
DWORD DWBuf; 
}swap; 

unsigned char *a; 
unsigned char *b; 
swap.DWBuf = 0xaabbccdd; 

a = &swap.BBuf[1]; 
b = &swap.BBuf[2]; 

*a ^= *b; 
*b ^= *a; 
*a ^= *b; 

स्वैप करने के लिए और अब परिणाम

है vould
swap.DWbuf == 0xaaccbbdd; 
2

एच mmm, पता नहीं क्या हुआ, यह वास्तव में शुरू करने से पहले यह मेरा जवाब प्रस्तुत किया।

पहले मुझे नहीं लगता था कि मैं इसे केवल दो रजिस्टरों के साथ कर सकता हूं लेकिन फिर मैंने फैसला किया कि मैं कर सकता हूं और कर सकता हूं। ये समाधान केवल रजिस्टर हैं, कोई मेमोरी नहीं है (एलडीआर आर 0 के अलावा, = जिसे आप चार निर्देशों के साथ प्रतिस्थापित कर सकते हैं)। यदि आप मेमोरी और हम्म का उपयोग करते हैं, तो दो रजिस्ट्रार आप शायद निर्देशों की संख्या को घटा सकते हैं, str, bic, bic, ldrb, orr lsl, ldrb, orr lsl। ठीक है, मैंने इसे एक निर्देश में कम किया है, लेकिन फिर आपको मेमोरी लोकेशन और स्टोर्स और लागत चक्रों की आवश्यकता होती है ताकि मेमोरी के साथ मेमोरी और मेरे लिए अधिक चक्र हो सकें। किसी और के पास कुछ अच्छी चाल हो सकती है। मुझे लगता है कि कुछ नए कोरों में एंडियन स्वैप निर्देश है जो इसे और भी आसान बना देगा।

.globl midswap 
midswap: 
    mov r2,r0,lsl #8  ;@ r2 = BBCCDDAA 
    mov r3,r0,lsr #8  ;@ r3 = DDAABBCC (this might drag a sign bit, dont care) 
    and r2,r2,#0x00FF0000 ;@ r2 = 00CC0000 
    and r3,r3,#0x0000FF00 ;@ r3 = 0000BB00 
    bic r0,r0,#0x00FF0000 ;@ r0 = AA00CCDD 
    bic r0,r0,#0x0000FF00 ;@ r0 = AA0000DD 
    orr r0,r0,r2   ;@ r0 = AACC00DD 
    orr r0,r0,r3   ;@ r0 = AACCBBDD 
    bx lr ;@ or mov pc,lr for older arm cores 


.globl tworegs 
tworegs: 
    mov r2,r0,ror #8  ;@ r2 = DDAABBCC 
    bic r2,r2,#0xFF000000 ;@ r2 = 00AABBCC 
    bic r2,r2,#0x00FF0000 ;@ r2 = 0000BBCC 
    orr r2,r2,ror #16  ;@ r2 = BBCCBBCC 
    bic r2,r2,#0xFF000000 ;@ r2 = 00CCBBCC 
    bic r2,r2,#0x000000FF ;@ r2 = 00CCBB00 
    bic r0,r0,#0x00FF0000 ;@ r0 = AA00CCDD 
    bic r0,r0,#0x0000FF00 ;@ r0 = AA0000DD 
    orr r0,r0,r2   ;@ r0 = AACCBBDD 
    bx lr 

testfun: 
    ldr r0,=0xAABBCCDD 
    bl midswap 
8

उस दिन वापस हम इस तरह की चालबाजी के लिए ईओआर पर भारी निर्भर थे।

आप इसे 4 चक्रों में कर सकते हैं।

सबसे पहले, हम तथ्य यह है कि जरूरत है: एक^(ए^बी) = बी

हम 0xAABBCCDD के साथ शुरू, और हम 0xAACCBBDD चाहते हैं। वहां पहुंचने के लिए, हमें 0x00EEEE00^0xAABBCCDD, की आवश्यकता है जहां ईई = बीबी^सीसी।

अब, हम कुछ चक्रों की जरूरत 00EEEE00 निर्माण करने के लिए:

eor  r1,r0,r0,lsr #8 
and  r1,r1,#0xFF00 
orr  r1,r1,r1,lsl #8 
eor  r0,r0,r1 

ग में:

t=x^(x>>8); 
t=t&0xFF00; 
t=t|(t<<8); 
x^=t; 

प्रत्येक पंक्ति के बाद, परिणाम गणना की है: के साथ शुरू: AABBCCDD

eor XXXXEEXX 
and 0000EE00 
orr 00EEEE00 
eor AACCBBDD 

यह किसी भी 32 बिट एआरएम कोर पर काम करेगा।

0

आप बीएफआई उपयोग कर सकते हैं और UBFX वे अपने काम आसान

संबंधित मुद्दे