-
1 # 使用者5763541389079
-
2 # 藍風24
在8086等CPU處理器中可按下面例子。 微控制器為例。
通常把在立即定址方式指令中給出的數稱為立即數。
立即數可以是8位、16位或32位,該數值緊跟在操作碼之後。如果立即數為16位或32位,那麼,它將按“高高低低”的原則進行儲存。例如:
MOV AH, 80H ADD AX, 1234H MOV ECX, 123456H
MOV B1, 12H MOV W1, 3456H ADD D1, 32123456H
其中:B1、W1和D1分別是位元組、字和雙字單元。
以上指令中的第二運算元(源運算元)都是立即數,在組合語言中,規定:立即數不能作為指令中的第一運算元(目的運算元)。該規定與高階語言中“賦值語句的左邊不能是常量”的規定相一致。
立即數定址方式通常用於對通用暫存器或記憶體單元賦初值。
下面以ARM彙編編譯器為例:
立即數方式:每個立即數由一個8位的常數迴圈右移偶數位得到。其中迴圈右移的位數由一個4位二進位制的兩倍表示。如果立即數記作
這樣並不是每一個32位的常數都是合法的立即數,只有能夠透過上面構造方法得到的才是合法的立即數。
下面的常數是合法的立即數:
0xff,0x104,0xff0,0xff00
下面的數不能透過上述構造方法得到,則不是合法的立即數:
0x101,0x102,0xFF1
同時按照上面的構造方法,一個合法的立即數可能有多種編碼方式。如0x3f0是一個合法的立即數,它可以採用下面兩種的編碼方式:
immed_8=0x3f,rotate_imm=0xe或者
immed_8=0xfc,rotate_imm=0xf
轉換為二進位制形式如下:
0x3f=0000 0000 0000 0000 0000 0000 0011 1111
0xe=14(十進位制) 2*14=28
∴,0x3f迴圈右移28位得到如下:
0000 0000 0000 0000 0000 0011 1111 0000=0x3f0
immed_8=0xfc,rotate_imm=0xf 的轉換如下:
0xfc=0000 0000 0000 0000 0000 0000 1111 1100
rotate_imm=0xf=15(十進位制) 15*2=30
所以0xfc迴圈右移30位得到如下結果:
0000 0000 0000 0000 0000 0011 1111 0000=0x3f0
可以看出,結果是一樣的!!!
但是,由於這種立即數的構造方法中包含迴圈移位操作,而迴圈移位操作會影響CPSR的條件標誌位C。因此,同一個合法的立即數由於採用了不同的編碼方式,將使得某些指令的執行產生不同的結果,這是不能允許的。ARM彙編編譯器按照下面的規則生成立即數的編碼。
1.當立即數數值在0和0xFF範圍時,零immmed_8=
2.其他情況下,彙編編譯器選擇使rotate_imm數值最小的編碼方式。所以0x3f0的正確表示法是第一種。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
解釋二:
一條典型的ARM指令語法格式分為如下幾個部分:
其指令編碼格式如下: 31-28 cond 27-25 001 24-21 opcode 20 S 19-16 Rn 15-12 Rd 11-0 (12位) operand2
對其中的operand2的常數表示式有這樣的規定:“該常數必須對應8位點陣圖,即常數是由一個8位的常數迴圈右移偶數位得到的。”這句話的意思是說,當用12位第二運算元來表示一個32位立即數時,採用的是將8位數透過移位的方式來實現的,其中12位第二
回覆列表
在8086等CPU處理器中可按下面例子。微控制器為例。通常把在立即定址方式指令中給出的數稱為立即數。立即數可以是8位、16位或32位,該數值緊跟在操作碼之後。如果立即數為16位或32位,那麼,它將按“高高低低”的原則進行儲存。例如:MOVAH,80H ADDAX,1234H MOVECX,123456HMOVB1,12H MOVW1,3456H ADDD1,32123456H其中:B1、W1和D1分別是位元組、字和雙字單元。以上指令中的第二運算元(源運算元)都是立即數,在組合語言中,規定:立即數不能作為指令中的第一運算元(目的運算元)。該規定與高階語言中“賦值語句的左邊不能是常量”的規定相一致。立即數定址方式通常用於對通用暫存器或記憶體單元賦初值。下面以ARM彙編編譯器為例:立即數方式:每個立即數由一個8位的常數迴圈右移偶數位得到。其中迴圈右移的位數由一個4位二進位制的兩倍表示。如果立即數記作<immediate>,8位常數記作immed_8,4位的迴圈右移值記作rotate_imm,則有:<immediate>=immed_8迴圈右移(2*rotate_imm)這樣並不是每一個32位的常數都是合法的立即數,只有能夠透過上面構造方法得到的才是合法的立即數。下面的常數是合法的立即數:0xff,0x104,0xff0,0xff00下面的數不能透過上述構造方法得到,則不是合法的立即數:0x101,0x102,0xFF1同時按照上面的構造方法,一個合法的立即數可能有多種編碼方式。如0x3f0是一個合法的立即數,它可以採用下面兩種的編碼方式:immed_8=0x3f,rotate_imm=0xe或者immed_8=0xfc,rotate_imm=0xf轉換為二進位制形式如下:0x3f=000000000000000000000000001111110xe=14(十進位制)2*14=28∴,0x3f迴圈右移28位得到如下:00000000000000000000001111110000=0x3f0immed_8=0xfc,rotate_imm=0xf的轉換如下:0xfc=00000000000000000000000011111100rotate_imm=0xf=15(十進位制)15*2=30所以0xfc迴圈右移30位得到如下結果:00000000000000000000001111110000=0x3f0可以看出,結果是一樣的!!!但是,由於這種立即數的構造方法中包含迴圈移位操作,而迴圈移位操作會影響CPSR的條件標誌位C。因此,同一個合法的立即數由於採用了不同的編碼方式,將使得某些指令的執行產生不同的結果,這是不能允許的。ARM彙編編譯器按照下面的規則生成立即數的編碼。1.當立即數數值在0和0xFF範圍時,零immmed_8=<immediate>,rotate_imm=0.、2.其他情況下,彙編編譯器選擇使rotate_imm數值最小的編碼方式。所以0x3f0的正確表示法是第一種。/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////解釋二:一條典型的ARM指令語法格式分為如下幾個部分:<opcode>{<cond>}{S}<Rd>,<Rn>{,<operand2>}其中,<>內的項是必須的,{}內的項是可選的,如<opcode>是指令助記符,是必須的,而{<cond>}為指令執行條件,是可選的,如果不寫則使用預設條件AL(無條件執行)。opcode指令助記符,如LDR,STR等cond執行條件,如EQ,NE等S是否影響CPSR暫存器的值,書寫時影響CPSR,否則不影響Rd目標暫存器Rn第一個運算元的暫存器operand2第二個運算元其指令編碼格式如下:31-28cond27-2500124-21opcode20S19-16Rn15-12Rd11-0(12位)operand2對其中的operand2的常數表示式有這樣的規定:“該常數必須對應8位點陣圖,即常數是由一個8位的常數迴圈右移偶數位得到的。”這句話的意思是說,當用12位第二運算元來表示一個32位立即數時,採用的是將8位數透過移位的方式來實現的,其中12位第二