ARM:ARMアセンブリ言語と基礎アセンブリ命令
5366 ワード
1、どうしてアセンブリ言語を勉強するのですか.1)ハードウェア電源の初期化コードはアセンブリコードで作成する;2)コードをデバッグする場合、問題の解決はアセンブリコードを見る可能性がある.3)システムチューニング(製品全体の稼働効率の向上);memcpy:C言語関数プロトタイプ:アセンブリコード-効率の向上4)C言語では実現できないロジックがあり、例えばcでr 5レジスタregister int aにアクセスする;2、学習目標1)アセンブリ制御LEDランプを使用する;2)アセンブリを読むことができるコード.3、学ARMアセンブリ要学的内容アセンブリ指令偽指令偽操作
$: arm-cortex_a9-linux-gnueabi-as test.s -o test.o//コンパイルアセンブリコード$:arm-cortex_a9-linux-gnueabi-objdump -S test.o > 1.asm/逆アセンブリ4、ARMアセンブリの特徴アセンブリ言語であり、アシスト言語とも呼ばれる.1)ほとんどの命令は単周期命令である2)ほとんどの命令は条件付きで実行可能である.【条件コード】----------------------CMP:比較EQ:等しいNE:等しくないADD:加算CS:符号なし数がCC以上:符号なし数が5未満、ARMアセンブリ命令5.1分岐ジャンプ命令'B{cond}'分岐命令-goto{}に類似代表は有無、<>は欠落を表すエラー、condは命令実行の条件コード、target_addressは、コマンドジャンプのターゲットアドレスです.'BL{cond}'相対ジャンプ命令-関数呼び出しジャンプ範囲制限±32 Mと同様に、PC=PC±32 M【L】は、ハードウェアによってダウングレード命令の戻りアドレスをlrに自動的に保存することを決定し、関数呼び出し//BとBL命令の両方が命令中のターゲットアドレスにジャンプできるようにする.-アドレス関連コード/アドレス無関係コード'BX{cond}'絶対ジャンプ、4 G範囲BLX【X】状態切替付き分岐ジャンプ5.2データ処理指令0)シフト操作lsl:論理左シフトlogical shift left,最低位補0 lsr:論理右シフトlogical shift right,最高位補0 asr:算術右シフトarithmetic shift right,最高位補記号ビット,最低位捨てror:サイクル右シフト,最高位補低位が新しい最高位rrxになる:拡張ビット付きサイクル右シフト,最高位拡張cpsrのCビット1)データ伝送命令'MOV{cond}{s}cond:条件実行可能s:操作結果がcpsr N/Z/CビットRdに影響する:ターゲットレジスタoperand:ターゲット操作数即時数:mov r 0,#1/*即時数の合法性の問題に注意この即時数は、1個の8 bitビット数サイクルを右シフトすることにより*/レジスタ:mov r 0,r 1@r 0=r 1レジスタシフト後の値:mov r 0,r 1,LSL 2@r 0=r 1*4 mov r 0,#0@r 0レジスタmovs r 0,#0@r 0=0 N=0 Z=1 C=0 movcss r 0,r 2'MVN r 0,#1@r 0=~(1)2)算術演算命令'ADD{cond}{s}加算cond:条件コードs:操作結果影響cpsr N/Z/C/VビットRd:ターゲットレジスタ、r 0~r 15のいずれかのRm:1番目の操作数、r 0~r 15のいずれかのoperand:2番目の操作数即時数:add r 0,r 1,#8@r 0=r 1+8//エラー例:add r 0,#8,r 1レジスタ:add r 0,r 1,r 2@r 0=r 1+r 2レジスタシフト後の値:add r 0,r 1,r 2,lsl#2@r 0=r 1+r 2*4 add r 0,r 1,r 2@r 0=r 1+r 2 adds r 0,r 1,r 2@r 0=r 1+r 2操作結果r 0はN/Z/C/Vビット'ADC r 0,r 1に影響し、r 2@r 0=r 1+r 2+Cキャリー付き加算指令64ビット加算:高低加算r 0 r 1被加算r 2 r 3およびr 0 r 1 adds r 1,r 1,r 3@C adc r 0,r 0を変更し、 r2 @r0=r0+r2+C 'SUB/SBC/RSB{cond} {s} ,減算cond:条件実行s:操作結果影響cpsr N/Z/C/V//注意Cビットへの影響://最上位に借方がない場合-C=1-例えば100-20//最上位に借方-C=0-例えば20-100 Rd:ラベルレジスタr 0~r 15のいずれかのRm:第1のオペランド、r 0~r 15いずれかのoperand:2番目のオペランド(同ADD)即時数レジスタレジスタシフト後の値sub r 0,r 1,r 2@r 0=r 1-r 2 sub r 0,r 1,#8@r 0=r 1-8 sub r 0,r 1,r 2,lsl 1@r 0=r 1-r 2*2'SBC r 0, r1, r2 @ r0=r1-r2-NOT(C) rsb r0, r1, r2 @r0=r2-r1 rsb r0, r0,#0@r 0=0-r 0 64 bit減算:高低被減数r 0 r 1減数r 2 r 3差r 0 r 1 subs r 1,r 1,r 1,r 3@r 1=r 1-r 3 if(r 1>r 3){C=1}if(r 1 sbc r 0,r 0,r 2@r 0=r 0-r 2-NOT(C)練習一:
アセンブリ言語を使用して1〜10の累積和を求め、結果はr 0に保存される.
$: arm-cortex_a9-linux-gnueabi-as sum.s -o sum.o $: arm-cortex_a9-linux-gnueabi-ld sum.o-o sum//はシミュレーションソフトqemuを通じて、PC機でarm coreの実行過程をシミュレートしてqemuをインストールすることができます:ネットワークインストール:$:sudo apt-get install qemu...非ネットワークインストール:$:cd~/downloads/qemu$:sudo dpkg-i*.deb再コンパイルsumプログラム:$:cd-$:arm-cortex_a9-linux-gnueabi-as sum.s -o sum.o -g $: arm-cortex_a9-linux-gnueabi-ld sum.o-o sumデバッグ実行プログラム:$:qemu-arm-g 1234 sum//1234ポートのために別のshellウィンドウを開き、cdはプログラムファイルディレクトリに入ります$:arm-cortex_a9-linux-gnueabi-gdb sum (gdb) target remote 192.168.1.8:1234//localhost(ip)(gdb)b 8(gdb)c(gdb)info reg r 1//r 1レジスタの値を表示し、r 1=10(gdb)n(gdb)info reg r 1//r 1=9(gdb)b 16(gdb)c(gdb)info reg r 0//r 0=19注意:$:arm-cortex_a9-linux-gnueabi-gdb sum arm-cortex_a9-linux-gnueabi-gdb:/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.16`not found(required by arm-cortex_a 9-linux-gnueabi-gdb)このとき必要なのはlibc 6をインストールするライブラリ:$:cd~/downloads/$:sudo dpkg-i*である.deb 3)論理演算命令'AND/ORR/EOR{cond}{s},'and r 0,r 1,#0 x 80@r 0=r 1&0 x 80 orr 5,r 8,r 7@r 5=r 8|r 7 eor r 5,r 6,r 7,lsl 2@r 5=r 6^(r 7*4)r 0中のbit 15ビットを逆?mov r 1,#1 eor r 0,r 0,r 1,lsl#15'BIC{cond}{s},'bic r 0,r 0,#0 x 08@r 0のbit 3ビットをクリアし、他のbit 3ビットをそのままbic r 0,r 0,#0 xff@r 0の8ビットすべてをクリアr 0のbit 7ビットをクリアし、他のビットをそのままにしますか?move r 1,#1 bic r 0,r 0,r 1 lsl#7 4)比較試験命令この種類の命令はsを加えず、デフォルトでcpsrに影響を及ぼすN/Z/C/Vビット演算結果は保存されない. 'CMP/CMN{cond} , ' cmp r0, #0x08 @alu_out=r0-0x08//alu_out論理ユニット@if(r 0<0 x 08)N=1逆N=0@if(r 0=0 x 08)Z=1逆Z=0@if(r 0>0 x 08)C=0逆C=1逆C=1 cmp r 1 r2 cmp r1, r2, lsl #1 'TST{cond} , tst r1, #0x08 @ alu_out=r 1&0 x 08@alu_によるout取値去影響cpsr N/Z/C/V@試験r 1 bit 3が0である場合r 1 bit 3が0である場合、Z=1'TEQ{cond},teq r 1,r 2@alu_out=r 1^r 2 2 2データが等しい場合alu_out=0,Z=1練習2:2つのデータの最大公約数を求める.r 0 r 1 eg:120 48//毎回減算し、結果を演算の数と比較して、小さい放有側72 48 24//r 0,r 1の2つのレジスタの数が等しいとき、結果r 0 r 1を得る
/** - **/
.text @
.code 32 @ ARM
.global start @ start
start:
mov r0, #10 @ r0=10
b . @ goto ,
.end @
$: arm-cortex_a9-linux-gnueabi-as test.s -o test.o//コンパイルアセンブリコード$:arm-cortex_a9-linux-gnueabi-objdump -S test.o > 1.asm/逆アセンブリ4、ARMアセンブリの特徴アセンブリ言語であり、アシスト言語とも呼ばれる.1)ほとんどの命令は単周期命令である2)ほとんどの命令は条件付きで実行可能である.【条件コード】----------------------CMP:比較EQ:等しいNE:等しくないADD:加算CS:符号なし数がCC以上:符号なし数が5未満、ARMアセンブリ命令5.1分岐ジャンプ命令'B{cond}'分岐命令-goto{}に類似代表は有無、<>は欠落を表すエラー、condは命令実行の条件コード、target_addressは、コマンドジャンプのターゲットアドレスです.'BL{cond}'相対ジャンプ命令-関数呼び出しジャンプ範囲制限±32 Mと同様に、PC=PC±32 M【L】は、ハードウェアによってダウングレード命令の戻りアドレスをlrに自動的に保存することを決定し、関数呼び出し//BとBL命令の両方が命令中のターゲットアドレスにジャンプできるようにする.-アドレス関連コード/アドレス無関係コード'BX{cond}'絶対ジャンプ、4 G範囲BLX【X】状態切替付き分岐ジャンプ5.2データ処理指令0)シフト操作lsl:論理左シフトlogical shift left,最低位補0 lsr:論理右シフトlogical shift right,最高位補0 asr:算術右シフトarithmetic shift right,最高位補記号ビット,最低位捨てror:サイクル右シフト,最高位補低位が新しい最高位rrxになる:拡張ビット付きサイクル右シフト,最高位拡張cpsrのCビット1)データ伝送命令'MOV{cond}{s}cond:条件実行可能s:操作結果がcpsr N/Z/CビットRdに影響する:ターゲットレジスタoperand:ターゲット操作数即時数:mov r 0,#1/*即時数の合法性の問題に注意この即時数は、1個の8 bitビット数サイクルを右シフトすることにより*/レジスタ:mov r 0,r 1@r 0=r 1レジスタシフト後の値:mov r 0,r 1,LSL 2@r 0=r 1*4 mov r 0,#0@r 0レジスタmovs r 0,#0@r 0=0 N=0 Z=1 C=0 movcss r 0,r 2'MVN r 0,#1@r 0=~(1)2)算術演算命令'ADD{cond}{s}加算cond:条件コードs:操作結果影響cpsr N/Z/C/VビットRd:ターゲットレジスタ、r 0~r 15のいずれかのRm:1番目の操作数、r 0~r 15のいずれかのoperand:2番目の操作数即時数:add r 0,r 1,#8@r 0=r 1+8//エラー例:add r 0,#8,r 1レジスタ:add r 0,r 1,r 2@r 0=r 1+r 2レジスタシフト後の値:add r 0,r 1,r 2,lsl#2@r 0=r 1+r 2*4 add r 0,r 1,r 2@r 0=r 1+r 2 adds r 0,r 1,r 2@r 0=r 1+r 2操作結果r 0はN/Z/C/Vビット'ADC r 0,r 1に影響し、r 2@r 0=r 1+r 2+Cキャリー付き加算指令64ビット加算:高低加算r 0 r 1被加算r 2 r 3およびr 0 r 1 adds r 1,r 1,r 3@C adc r 0,r 0を変更し、 r2 @r0=r0+r2+C 'SUB/SBC/RSB{cond} {s} ,減算cond:条件実行s:操作結果影響cpsr N/Z/C/V//注意Cビットへの影響://最上位に借方がない場合-C=1-例えば100-20//最上位に借方-C=0-例えば20-100 Rd:ラベルレジスタr 0~r 15のいずれかのRm:第1のオペランド、r 0~r 15いずれかのoperand:2番目のオペランド(同ADD)即時数レジスタレジスタシフト後の値sub r 0,r 1,r 2@r 0=r 1-r 2 sub r 0,r 1,#8@r 0=r 1-8 sub r 0,r 1,r 2,lsl 1@r 0=r 1-r 2*2'SBC r 0, r1, r2 @ r0=r1-r2-NOT(C) rsb r0, r1, r2 @r0=r2-r1 rsb r0, r0,#0@r 0=0-r 0 64 bit減算:高低被減数r 0 r 1減数r 2 r 3差r 0 r 1 subs r 1,r 1,r 1,r 3@r 1=r 1-r 3 if(r 1>r 3){C=1}if(r 1 sbc r 0,r 0,r 2@r 0=r 0-r 2-NOT(C)練習一:
アセンブリ言語を使用して1〜10の累積和を求め、結果はr 0に保存される.
/** - **/
.text
.code 32
.global _start
_start:
mov r0, #0 @// 0 r0
mov r1, #10 @// 10 r1
sub_loop:
add r0, r0, r1 @// r0=r0+r1;
sub r1, r1, #1 @// r1=r1-1;
cmp r1, #0 @// :r1 ?= 0
bne sub_loop @// ne b
b .
.end
/** ------------------------------------------------------- **/
$: arm-cortex_a9-linux-gnueabi-as sum.s -o sum.o $: arm-cortex_a9-linux-gnueabi-ld sum.o-o sum//はシミュレーションソフトqemuを通じて、PC機でarm coreの実行過程をシミュレートしてqemuをインストールすることができます:ネットワークインストール:$:sudo apt-get install qemu...非ネットワークインストール:$:cd~/downloads/qemu$:sudo dpkg-i*.deb再コンパイルsumプログラム:$:cd-$:arm-cortex_a9-linux-gnueabi-as sum.s -o sum.o -g $: arm-cortex_a9-linux-gnueabi-ld sum.o-o sumデバッグ実行プログラム:$:qemu-arm-g 1234 sum//1234ポートのために別のshellウィンドウを開き、cdはプログラムファイルディレクトリに入ります$:arm-cortex_a9-linux-gnueabi-gdb sum (gdb) target remote 192.168.1.8:1234//localhost(ip)(gdb)b 8(gdb)c(gdb)info reg r 1//r 1レジスタの値を表示し、r 1=10(gdb)n(gdb)info reg r 1//r 1=9(gdb)b 16(gdb)c(gdb)info reg r 0//r 0=19注意:$:arm-cortex_a9-linux-gnueabi-gdb sum arm-cortex_a9-linux-gnueabi-gdb:/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.16`not found(required by arm-cortex_a 9-linux-gnueabi-gdb)このとき必要なのはlibc 6をインストールするライブラリ:$:cd~/downloads/$:sudo dpkg-i*である.deb 3)論理演算命令'AND/ORR/EOR{cond}{s},'and r 0,r 1,#0 x 80@r 0=r 1&0 x 80 orr 5,r 8,r 7@r 5=r 8|r 7 eor r 5,r 6,r 7,lsl 2@r 5=r 6^(r 7*4)r 0中のbit 15ビットを逆?mov r 1,#1 eor r 0,r 0,r 1,lsl#15'BIC{cond}{s},'bic r 0,r 0,#0 x 08@r 0のbit 3ビットをクリアし、他のbit 3ビットをそのままbic r 0,r 0,#0 xff@r 0の8ビットすべてをクリアr 0のbit 7ビットをクリアし、他のビットをそのままにしますか?move r 1,#1 bic r 0,r 0,r 1 lsl#7 4)比較試験命令この種類の命令はsを加えず、デフォルトでcpsrに影響を及ぼすN/Z/C/Vビット演算結果は保存されない. 'CMP/CMN{cond} , ' cmp r0, #0x08 @alu_out=r0-0x08//alu_out論理ユニット@if(r 0<0 x 08)N=1逆N=0@if(r 0=0 x 08)Z=1逆Z=0@if(r 0>0 x 08)C=0逆C=1逆C=1 cmp r 1 r2 cmp r1, r2, lsl #1 'TST{cond} , tst r1, #0x08 @ alu_out=r 1&0 x 08@alu_によるout取値去影響cpsr N/Z/C/V@試験r 1 bit 3が0である場合r 1 bit 3が0である場合、Z=1'TEQ{cond},teq r 1,r 2@alu_out=r 1^r 2 2 2データが等しい場合alu_out=0,Z=1練習2:2つのデータの最大公約数を求める.r 0 r 1 eg:120 48//毎回減算し、結果を演算の数と比較して、小さい放有側72 48 24//r 0,r 1の2つのレジスタの数が等しいとき、結果r 0 r 1を得る
/** - gcd.s **/
.text
.global _start
.global gcd
.code 32
_start:
mov r0, #20 @ 1
mov r1, #12 @ 2
gcd:
cmp r0, r1
beq gcd_ok
subcs r0, r0, r1
subcc r1, r1, r0
b gcd
gcd_ok:
@ R0,R1 。
b .
.end