0

私は次のような課題に取り組んでいます: アセンブリ言語の C = (A + B)^2 を機械語に翻訳してください。私は次のようにアセンブリプログラムを調査して書き出すことから始めました。

MOV AX, A ; Move A to Register Ax 
ADD AX, B; Add B to A 
IMUL AX; Square(A+B) 
MOV BX, C ; Load c to Register Bx 
MOV BX, AX ; Mov (A+B)^2 to C in BX. 

Pls はこのアセンブリ コードについてあまり確信が持てず、それを機械語に変換する方法を知りません

4

3 に答える 3

1

変数 A、B、および C がメモリ内変数である場合、コードはほぼ正しいです。

これを変更するだけです

MOV BX, C ; Load c to Register Bx 
MOV BX, AX ; Mov (A+B)^2 to C in BX. 

これに

MOV C, AX ; Mov (A+B)^2 to C

アセンブリ言語プログラムは、アセンブリ言語で書かれたプログラムを入力として受け取るコンパイラに似たプログラムであるアセンブラを使用して、機械に変換します。

x86 アセンブラにはさまざまなものがあります。構文と機能がわずかに (場合によってはそれほどではない) 異なるため、いずれかを選択する必要があります。

あなたのコードから NASM を使用して DOS 用の 16 ビット .COM プログラムを作成するとしたら、次のように書き直す必要があります。

; file: AddSquar.asm
; to assemble with NASM: nasm -f bin AddSquar.asm -l AddSquar.lst -o AddSquar.com

BITS 16 ; 16-bit code
ORG 100H ; IP of first instruction is expected to be 100H in .COM programs

    MOV     AX, [A] ; Move A to Register Ax 
    ADD     AX, [B] ; Add B to A 
    IMUL    AX      ; Square(A+B) 
    MOV     [C], AX ; Mov (A+B)^2 to C

    RET ; terminate .COM program, return to DOS

A   DW 3
B   DW 4
C   DW 0

作成されたリスト ファイル (AddSquar.lst) には、エンコードされたすべての命令が含まれています (ただし、何らかの理由ORG 100Hで、すべてのアドレスで考慮されていません。おそらく、すべてのアドレスは常にコードの先頭に対して相対的に表示されます)。

 1                                  ; file: AddSquar.asm
 2                                  ; to assemble with NASM: nasm -f bin AddSquar.asm -l AddSquar.lst -o AddSquar.com
 3                                  
 4                                  BITS 16 ; 16-bit code
 5                                  ORG 100H ; IP of first instruction is expected to be 100H in .COM programs
 6                                  
 7 00000000 A1[0D00]                    MOV     AX, [A] ; Move A to Register Ax 
 8 00000003 0306[0F00]                  ADD     AX, [B] ; Add B to A 
 9 00000007 F7E8                        IMUL    AX      ; Square(A+B) 
10 00000009 A3[1100]                    MOV     [C], AX ; Mov (A+B)^2 to C
11                                  
12 0000000C C3                          RET ; terminate .COM program, return to DOS
13                                  
14 0000000D 0300                    A   DW 3
15 0000000F 0400                    B   DW 4
16 00000011 0000                    C   DW 0

バイナリ ファイル (AddSquar.com) の 16 進ビューアー/エディターでも同じ結果が得られます。

0000000000: A1 0D 01 03 06 0F 01 F7 │ E8 A3 11 01 C3 03 00 04  Ў♪☺♥♠☼☺чиЈ◄☺Г♥ ♦
0000000010: 00 00 00                │

逆アセンブリでエンコードされた命令も確認できます。

00000100  A10D01            mov ax,[0x10d]
00000103  03060F01          add ax,[0x10f]
00000107  F7E8              imul ax
00000109  A31101            mov [0x111],ax
0000010C  C3                ret
0000010D  0300              add ax,[bx+si]
0000010F  0400              add al,0x0
00000111  0000              add [bx+si],al

上記の場合、次のように NDISASM を使用しましたndisasm -b 16 -o 0x100 AddSquar.com

手動でアセンブリ コードをマシン コードに変換する必要がある場合は、自分で行う必要があると思います。なぜなら、SO は命令エンコーディングに関する広範な講義を行うのに適した場所ではないからです。

Intel または AMD から CPU のマニュアルをオンラインで入手します。彼らは無料です。命令のエンコードに関する章を読んでから、手作業で行ってください。

于 2013-04-11T14:04:08.187 に答える
0

(A+B)² の計算は正しいですが、正しい場所に保存していないようです。

mov ax, A  ; Move A to Register Ax 
add ax, B  ; Add B to A 
imul ax    ; Square(A+B) 
mov C, ax  ; Move (A+B)^2 to C. 

しかしもちろん、それはA、B、Cが実際に何であるかによって異なります...

于 2013-04-11T13:57:53.530 に答える
-1

質問:

次の 2 つの二項定理のサブルーチンを記述するアセンブリ言語コードを記述します。

SROUTINE_SUM:    SUM_SQ = (A+B)2 = A2 + B2 + 2*A*B

SROUTINE_DIF:    DIF_SQ = (A-B)2 = A2 + B2 - 2*A*B

ASUM_SQ, DIF_SQ,と B は定義済みのデータ ラベルで、SROUTINE_SUMSROUTINE_DIFはサブルーチン名です。

A と B のテスト値は、それぞれ 3 と 2 です。

SUM_SQ と で計算された値を示す AFD デバッガーのスナップショットを添付する必要がありDIF_SQます。

于 2014-05-21T07:00:55.223 に答える