2

これは 3 つの質問を 1 つにまとめたようなものです。

1-だから私はここSOで私の問題に対する答えを探していて、誰かがどこかからこれを引用しました:

スタック セグメントのアドレス サイズ属性によって、スタック ポインターのサイズ (16、32、または 64 ビット) が決まります。現在のコード セグメントのオペランド サイズ属性によって、スタック ポインターが減少する量 (2、4、または 8 バイト) が決まります。

私のようなアセンブラーの初心者が理解できる方法で誰かがこれを説明してもらえますか?

2-問題は、私がこの小さなスタックを作成したことです:

setStack:                  ; setup a small stack at 0x9B000

  cli                      ; disable interrupts
  mov AX, 0x9000
  mov SS, AX
  mov SP, 0xB000
  sti                      ; re-enable interrupts

引用符 1 の私の (最も確実な欠如の) 理解により、このスタックには 16 ビットのポインターがあり、プッシュ/ポップ命令は、呼び出されたときに 2 バイトをデクリメント/インクリメントすると想定しましたか? 私は正しく仮定しましたか?

3- 私が正しく仮定したと仮定すると (つまり、たとえそうでなくても、答えたかのようにこの次の質問に答えてください)、次のステートメントはスタック上で何を実行しますか?

push ECX                   ; ECX is a 32 bit register

Stack Overflow の親切な住人に感謝します。

4

2 に答える 2

1

スタックセグメントが16ビットスタックで設定されている場合、プッシュ/ポップはSPを参照し、スタックは2バイト境界に整列する必要があります。16ビットレジスタをプッシュすると1スロットが占有され、32ビットレジスタをプッシュすると2スロットが占有されます。次のコードを使用して、これを自分で確認できます。

push eax
pop ax
pop bx

スタックセグメントが32ビットスタックで設定されている場合、プッシュ/ポップはESPを参照し、スタックは4バイト境界に配置する必要があります。32ビットレジスタをプッシュすると、1つのスロットが占有されます。16ビットレジスタをプッシュすると、スタックがずれます。これは悪いことです。

次のURLは、Intelマニュアルのプッシュ命令の仕様のコピーです。プッシュ命令用のステートマシンを取り付けました。

http://www.rz.uni-karlsruhe.de/rz/docs/VTune/reference/vc266.htm

IF StackAddrSize  32
THEN

IF OperandSize  32
THEN
ESP  ESP - 4;
SS:ESP  SRC; (* push doubleword *)
ELSE (* OperandSize  16*)
ESP  ESP - 2;
SS:ESP  SRC; (* push word *)
FI;

ELSE (* StackAddrSize  16*)

IF OperandSize  16
THEN
SP  SP - 2;
SS:SP  SRC; (* push word *)
ELSE (* OperandSize  32*)
SP  SP - 4;
SS:SP  SRC; (* push doubleword *)
FI;

FI;
于 2012-09-07T10:06:20.440 に答える
0

それを試してみてください!(あなたは「あなた自身のOS」にいるように見えますが、おそらくDOSが利用可能ですか?)

; nasm -f bin -o test32.com test32.asm
bits 16
org 100h

mov eax, 11112222h
push eax
pop ax
pop dx
call ax2hex
mov ax, dx
call ax2hex
ret

;-------------------
ax2hex:
    push cx
    push dx

    mov cx, 4           ; four digits to show

.top
    rol ax, 4           ; rotate one digit into position
    mov dl, al          ; make a copy to process
    and dl, 0Fh         ; mask off a single (hex) digit
    cmp dl, 9           ; is it in the 'A' to 'F' range?
    jbe .dec_dig        ; no, skip it
    add dl, 7           ; adjust
.dec_dig:
    add dl, 30h         ; convert to character

    push ax
    mov ah, 2           ; print the character
    int 21h
    pop ax

    loop .top

    pop dx
    pop cx
    ret
;--------------------------

重要な唯一の意見は、CPU の意見です。

ベスト、フランク

于 2012-09-07T10:47:40.580 に答える