こんにちはすべてできます誰でも1つのplzが8086アセンブリ言語で2D配列を処理する方法を教えてくれます。私はアセンブリ言語プログラミングの初心者です。ありがとう
2 に答える
マダールのリンクはほとんどそれをカバーしています、あなたはそれを読み通しましたか?
たとえば、Cプログラミングレベルの2D配列をすでに理解している場合は、アセンブラが次の論理ステップです。
たとえば、8ビットバイトを使用すると、配列z [1] [2]は2行目から3番目の項目になります。そのように考えたい場合は、アドレスを計算するために、zのCアドレスに最初のインデックス時間を加えたものになります。配列の幅。13バイト幅に加えて2番目のインデックスがあるとすると、&z +(13 * 1)+2 =&z + 15;
x86コードではなく擬似コードを使用する(これが宿題の場合)。
;強引な ldr r0、=z;zのアドレスをr0にロードします mov r1、#13 mul r1、#1;これをレジスタにするか、メモリ位置からロードします mov r2、#2;これをレジスタにするか、メモリ位置からロードします r0、r1を追加 r0、r2を追加 ldrb r1、[r0];バイトを読み取る strb r3、[r0];バイトを書き込む ;命令セットでレジスタオフセットが許可されている場合 ldr r0、=z;zのアドレスをr0にロードします mov r1、#13 mul r1、#1 mov r2、#2 r1、r2を追加 ldrb r4、[r0、r1];バイトを読み取る strb r3、[r0、r1];バイトを書き込む ;または即時オフセットとオフセットがハードコーディングされている ldr r0、=z;zのアドレスをr0にロードします mov r1、#13 mul r1、#1 r0、r1を追加 ldrb r4、[r1、#2];バイトを読み取る strb r3、[r1、#2];バイトを書き込む
Cでループがあった場合
unsigned char x [4] [16]; unsigned char z [4] [16]; unsigned int ra、rb; for(ra = 0; ra <4; ra ++) {{ for(rb = 0; rb <16; rb ++) {{ x [ra] [rb] = z [ra] [rb]; } }
アセンブラへの変換は非常に簡単です。
ldr r0、= x ldr r1、= z mov r2、#0; ra アウター: mov r3、#0; rb 内側: mov r4、r2 lsl#2;16バイト幅 r4、r3を追加 ldrb r5、[r1、r4] strb r5、[r0、r4] r3、r3、#1を追加 cmp r3、#16 bneインナー r2、r2、#1を追加します cmp r2、#4 bneアウター
ブルートフォースは常に各プラットフォームで機能します。ブルートフォースはベースアドレス+(幅×最初のインデックス)+(2番目のインデックス×要素のサイズ)です。最適化は、実行しようとしていることに大きく依存します。たとえば、最初のアセンブリの例では、最初のインデックスがハードコードされている場合は1を掛けるのはばかげています。また、#2をレジスタに移動するのはばかげています。ハードコードされた数値、2を加算するだけです。1回の計算とループの計算によって、使用するレジスタの最適な数が変わる場合など、プラットフォームに乗算がない場合や問題がある場合は、可能であればアレイの累乗を2にするのが適切です。幅を変更できず、プラットフォームに乗算がないか、乗算が苦痛になる場合は、乗算を取り除くか、乗算を取り除くための他のトリックを考えてください。
たとえば、アドレスが2つのレジスタの合計である、ある種のレジスタオフセットアドレス指定[r0、r1]を持つプラットフォームは、追加を節約し、ベースアドレスレジスタの破壊を防ぎ、ループで再び使用できるようにします。ポインタを移動するときに破棄(* ptr ++)を使用してポインタスタイルを使用する場合は、ループの実装方法が変わる可能性があります。一部のプラットフォームでは、ベースレジスタを使用してそれに値を追加できます(例:[r0])。 #16はr0のアドレスを使用し、r0を使用した後にr0に16を追加するので、余分な追加命令を書き込む必要はありません... x86にそれがあるとは思いませんが、このタスクに使用できる他の機能があります。
総当たり攻撃から始めます。x86であるということは、タスクに十分なレジスタがない可能性があるため、ループ変数を保持するためにメモリを使用する必要がある可能性が高いことを意味します(x86にはメモリベースの命令がたくさんあるので問題ありません)。ロードとストアのバリエーションの利点。
;This code grabs data bits from accumulator and outputs it to the carry
Main:
clr C
mov A, #00101010b;
call array;
jmp Main;
array:
subb A, #80H; mov can work here if you did not clr C
cpl A; check for proper array location
mov B, #8; set division factor
DIV AB; bit offset contained in B;
mov R6,B;
subb A, #30H; this bit will allow you to mov around the chosen register
cpl A;
mov R7, A;
mov A, @R7; this is the array position
inc R6;
loop:
rlc A; this takes the array bit to the carry for easy access
djnz R6, loop;