0

2 つの引数を受け取るプロシージャを作成する必要があります: (スタック上):

  • 文字列のオフセット - バイト配列。

  • 文字列の長さ。

ローカル変数を作成し、文字列を変数にコピーする必要があります。

それでは印刷してみます。うまくいきません。

.model small
.stack 64

.data
str1 db "Hello world$"
len  dw $-str1

.code

print proc
    push bp ; save bp
    mov bp, sp
    mov cx, [bp+4]
    mov di, [bp+2]
    mov ah, 02
do1:
    mov dl, ss:[si]
    int 21H
    inc si
loop do1
    pop bp
    ret 4
endp print

cpy proc
   mov bp, sp
   mov si, [bp+2] ; string's offset
   mov cx, [bp+4] ; string's length
   sub sp, cx     ; create cx'th byte array
   mov di, sp
do:
   mov ax, [si]
   mov [di], ax
   inc si
   inc di
loop do
  add sp, [bp+4] ; restore stack
  ; print

  push len
  push sp
  call print

  ret 4
endp cpy

start:
    mov ax, @DATA
    mov ds, ax

    push len
    push offset str1
    call cpy

    mov al, 0
    mov ah, 4ch
    int 21H
end start

いくつかの「ランダムな」値を出力します。理由はわかりますか?

4

3 に答える 3

0

print proc
    push bp ; save bp
    mov bp, sp
    mov cx, [bp+4]
    mov di, [bp+2]

をプッシュbpすると、最初の (最後にプッシュされた) パラメータは になり[bp + 4]ます。[bp + 2]あなたの返信先住所です...これはランダムな文字を占めています...

于 2013-06-02T19:50:06.953 に答える
0

コピー手順では、ループしていません。文字列の最初のバイトのみをコピーしています。

また、ここで 2 バイトをコピーしています。

mov ax, [si]
mov [di], ax

次のようにする必要があります。

mov al, [si]
mov [di], al
cmp al, 0
je finished
inc si
inc di
jmp loop
于 2013-06-02T18:37:28.650 に答える
0

大きくなる前に小さく始める方が簡単かもしれません

次に、ルーチンを構築しながらデバッグできます

.data
str1 db "Hello world$"
.data1

mov si,data        ;stringstart
mov cx,data1-data  ;stringlength

do:
   mov al, [si]
   mov [di], al
   inc si
   inc di
loop do

より複雑になる前にそれを印刷し、印刷できることがわかったら、一度にステージごとに完全なスタック関数を構築します

于 2013-06-03T08:36:57.453 に答える