为什么ASM功能打印不正确?

时间:2016-06-02 15:02:35

标签: loops assembly io x86 mbr

我正在尝试编写一个小函数来在特定的内存位置打印以null结尾或固定长度的字符串。这是我的代码:

vbrstart:
    xor eax, eax
    mov sp, 0x7a00
    mov bp, 0x6000
    mov ss, ax
    mov ds, ax
    mov es, ax
    xor ebx, ebx
    xor ecx, ecx
    push strict dword initializing
    push strict word 0x0000
    call printmsg
    jmp end


;push strict dword memloc
;push strict word length
;call printmsg
printmsg:
    pop strict dword [store_ret]
    mov [store_cx], cx
    mov [store_esi], esi
    pop cx
    pop esi
    push eax
    push ebx
    mov ah, 0x0E
    mov bx, 0x0007
    cmp cx, 0x0000
    je printnullterm
printgivenlen:
    lodsb
    cmp cx, 0x0000
    je printdone
    int 10h
    dec cx
    jmp printgivenlen
printnullterm:
    lodsb
    cmp al, 0x00
    je printdone
    int 10h
    jmp printnullterm
printdone:
    pop ebx
    pop eax
    mov esi, [store_esi]
    mov cx, [store_cx]
    push strict dword [store_ret]
    ret
printdata:
    store_cx dw 0
    store_esi dd 0
    store_ret dd 0

end:
    hlt
    jmp end

initializing db 10,13,'Initializing...',0

测试时,它会无限打印,并且不会在空字节处停止。我在哪里弄错了?

2 个答案:

答案 0 :(得分:2)

我发现您的代码有两个问题:

  • 你已经写了一个bootloader。这样的程序以16位实地址模式运行。这意味着call的返回地址将是,而不是代码所期望的 dword

    printmsg:
    pop word [store_ret]
    
  • 您以危险的方式设置堆栈。您需要先更改SS寄存器,然后立即更改SP寄存器。

    xor ax, ax
    mov ss, ax      <<< Keep these together 
    mov sp, 0x7a00  <<< and in this order!
    

由于这是16位代码,因此无需将push / pop地址作为双字。

push word initializing
...
pop si

答案 1 :(得分:1)

您的筹码未与所有推送和弹出对齐。检查参数传递及其在例程中的用法。 首先,这是一个提示:

import java.util.Scanner;
import java.math.BigInteger;

// code for BST class taken from Sedgewick textbook, pp. 398-99   

public class CountBinarySearch {
    private class BST<Key extends Comparable<Key>, Value> {

        private Node root;

        private class Node {
        private Key key;
        private Value val;
        private Node left, right;
        private int N; // # nodes in subtree rooted here

        public Node(Key key, Value val, int N) {
            this.key = key;
            this.val = val;
            this.N = N;
        }
    }

    public int size() {
        return size(root);
    }

    private int size(Node x) {
        if (x==null) return 0;
        else return x.N;
    }

    public Value get(Key key) {
        return get(root, key);
    }

    private Value get(Node x, Key key) {
        if (x==null) return null;
        int cmp = key.compareTo(x.key);
        if (cmp < 0) return get(x.left, key);
        else if (cmp > 0) return get(x.right, key);
        else return x.val;
    }

    public void put(Key key, Value val) {
        root = put(root, key, val);
    }

    private Node put(Node x, Key key, Value val) {
        if (x==null) return new Node(key, val, 1);
        int cmp = key.compareTo(x.key);
        if (cmp<0) x.left = put(x.left, key, val);
        else if (cmp > 0) x.right = put(x.right, key, val);
        else x.val = val;
        x.N = size(x.left) + size(x.right) + 1;
        return x;
    }
} //end class BST


   private long theCount;

   public void CountBinarySearch( Scanner in ) {
    int n = in.nextInt();
    BST tree = new BST();
    BigInteger sum = BigInteger.valueOf(0);
    sum = sum.add(BigInteger.valueOf(countOrderings(tree)));
    BigInteger last8 = new BigInteger("Math.pow(10,8)");
    sum = sum.mod(last8);
    theCount = sum.longValue();
    return;
   }

public long countOrderings(BST t) {
    if (t==null) return 1;
    else {
        int a = numElements(t.left);
        int b = numElements(t.right);
        return aChooseb(a+b,b)*countOrderings(t.left)*countOrderings(t.right);
    } //end else
} //end countOrderings

public int numElements(BST t){
    return size(t);
} //end numElements

public double aChooseb(int a, int b) {
    if (b<0 || b>a) return 0;

    if (b>a/2) {
        b=a-b; //(n choose k) = (n choose (n-k))
    } //end if

    double denom = 1.0;
    double num = 1.0;
    for (int i = 0; i <= b; i++) {
        denom *= i;
        num *= (a+1-i);
    } //end for

    return num/denom;
} //end aChooseb

   public long getCount() { return theCount; }

   public static void main ( String[] args ) {
       Scanner in = new Scanner( System.in );
       int cases = in.nextInt();
       for (int c=0; c<cases; ++c) {
           CountBinarySearch cbs = new CountBinarySearch( in );
           System.out.println( cbs.getCount() );
       }
   }

} //end class CountBinarySearch