注册 登录
编程论坛 汇编论坛

大家帮我看看这个哪里错了

做个好人 发布于 2010-12-26 14:41, 601 次点击
找出buf数据块里最小的偶数(带符号字节数),以16进制形式输出.

DATA SEGMENT
SAVEREG    DB     50 DUP(?);
BUF   DB   66H,84H,94H,7AH,70H,69H;
COUNT EQU  ($-BUF)/1;  
DATA ENDS


CODE SEGMENT
    ASSUME CS:CODE,DS:DATA
MAIN    PROC  FAR;
    MOV    AX,DATA
    MOV    DS,AX
    ;此处输入代码段代码
    LEA    SI,BUF;       首地址;
    MOV    CX,COUNT;     个数;
    PUSH   SI;
    PUSH   CX;
    CALL   MINPROC;
    CALL   OUTPUT;
  
    MOV    AH,4CH;
    INT    21H;
;寻找最小元素。   
MINPROC   PROC   NEAR
    LEA    DI,SAVEREG;
    MOV    [DI],AX;
    MOV    [DI+2],BX;
    MOV    [DI+4],CX;
    MOV    [DI+6],DX;
    POP    DX;
    POP    SI;数组首地址;
    POP    CX;个数;
    PUSH   DX;
    MOV    AL,[SI];
SEARCH:   
    MOV    DL,[SI];
    TEST   DL,01H;
    JZ     AA1;
    JMP    AA2;
AA1:
    CMP    DL,AL;
    JL     AA3;
    JMP    AA2;
AA3:
    MOV    AL,DL;    改变al
AA2:
    INC    SI;
    LOOP   SEARCH;
    MOV    AH,0;
    POP    CX;
    PUSH   AX;
   
    PUSH   CX;
   
   
    LEA    DI,SAVEREG
    MOV    AX,[DI];
    MOV    BX,[DI+2];
    MOV    CX,[DI+4];
    MOV    DX,[DI+6];
RET
MINPROC  ENDP;
;寻找最小元素函数结束

;最小元素存在栈区里,下面的函数为从栈中取元素,然后以16进制输出。
OUTPUT    PROC   NEAR;
    LEA    DI,SAVEREG;
    MOV    [DI],AX;
    MOV    [DI+2],BX;
    MOV    [DI+4],CX;
    MOV    [DI+6],DX;
    POP   AX;
    POP    BX;              最小元素在栈里
    PUSH  AX;
   
    MOV  CH,4;
    MOV  CL,4;  
      
RLL:
    ROL  BX,CL;
    MOV  DL,BL;
      
    AND  DL,0FH;   
      
    ADD  DL,30H;
    CMP  DL,3AH;
    JB   SKIP;
    ADD  DL,7;
      
SKIP:  
    MOV  AH,2;
    INT  21H;
    DEC  CH;
    JNZ  RLL;
   
   
   
    MOV  DL,'H';
    MOV  AH,2;
    INT  21H;
    LEA    DI,SAVEREG
    MOV    AX,[DI];
    MOV    BX,[DI+2];
    MOV    CX,[DI+4];
    MOV    DX,[DI+6];
RET
OUTPUT  ENDP;
;16进制输出函数结束
MAIN   ENDP;
CODE   ENDS;
      END
   
6 回复
#2
zaixuexi2010-12-26 16:02
程序代码:
DATA SEGMENT
SAVEREG    DB     50 DUP(?);
BUF   DB   66H,84H,94H,7AH,70H,69H;
COUNT EQU  ($-BUF)/1;
DATA ENDS


CODE SEGMENT
    ASSUME CS:CODE,DS:DATA
MAIN    PROC  FAR;
START:
    MOV    AX,DATA
    MOV    DS,AX
    ;此处输入代码段代码
    LEA    SI,BUF;       首地址;
    MOV    CX,COUNT;     个数;
    PUSH   SI;
    PUSH   CX;
    CALL   MINPROC;
    CALL   OUTPUT;

    MOV    AH,4CH;
    INT    21H;
;
寻找最小元素。   
MINPROC   PROC   NEAR
    LEA    DI,SAVEREG;
    MOV    [DI],AX;
    MOV    [DI+2],BX;
    MOV    [DI+4],CX;
    MOV    [DI+6],DX;
    POP    DX;
    POP    CX;个数;
    POP    SI;数组首地址;
    PUSH   DX;
    MOV    AL,[SI];
SEARCH:   
    MOV    DL,[SI];
    TEST   DL,01H;
    JZ     AA1;
    JMP    AA2;
AA1:
    CMP    DL,AL;
    JL     AA3;
    JMP    AA2;
AA3:
    MOV    AL,DL;    改变al
AA2:
    INC    SI;
    LOOP   SEARCH;
    MOV    AH,0;
    POP    CX;
    PUSH   AX;
  
    PUSH   CX;
   
   
    LEA    DI,SAVEREG
    MOV    AX,[DI];
    MOV    BX,[DI+2];
    MOV    CX,[DI+4];
    MOV    DX,[DI+6];
RET
MINPROC  ENDP;
;
寻找最小元素函数结束

;最小元素存在栈区里,下面的函数为从栈中取元素,然后以16进制输出。
OUTPUT    PROC   NEAR;
    LEA    DI,SAVEREG;
    MOV    [DI],AX;
    MOV    [DI+2],BX;
    MOV    [DI+4],CX;
    MOV    [DI+6],DX;
    POP   AX;
    POP    BX;              最小元素在栈里
    PUSH  AX;
   
    MOV  CH,4;
    MOV  CL,4;
      
RLL:
    ROL  BX,CL;
    MOV  DL,BL;
      
    AND  DL,0FH;   
      
    ADD  DL,30H;
    CMP  DL,3AH;
    JB   SKIP;
    ADD  DL,7;
      
SKIP:
    MOV  AH,2;
    INT  21H;
    DEC  CH;
    JNZ  RLL;
   
   
   
    MOV  DL,'H';
    MOV  AH,2;
    INT  21H;
    LEA    DI,SAVEREG
    MOV    AX,[DI];
    MOV    BX,[DI+2];
    MOV    CX,[DI+4];
    MOV    DX,[DI+6];
RET
OUTPUT  ENDP;
;
16进制输出函数结束
MAIN   ENDP;
CODE   ENDS;
END START
START要记得加,END START告诉编译器,程序的入口地址
MINPROC中
    POP    SI;数组首地址;
    POP    CX;个数;
->
    POP    CX;个数;栈是后入先出的访问方式
    POP    SI;数组首地址;
因为你调用的地方是
   PUSH   SI; SI先入栈
   PUSH   CX;
---------------------------------------------------------------------------------------------------
你的设计像是子程序通过栈传递,但是这么写不太好,你把返回地址压来压去的.
保存寄存器也最好不要开数据空间,直接PUSH就好了.
书上应该有讲子程序通过栈传递的例子吧,或者你就直接寄存器传递就行了,参数少.可能有说的不对的地方,呵呵.
#3
xiaomarn2010-12-26 17:38
程序代码:
DATA SEGMENT
    SAVEREG    DB     50 DUP(?);
    BUF   DB   66H,84H,94H,7AH,70H,69H;
    COUNT EQU  ($-BUF)/1;

DATA ENDS


CODE SEGMENT
    ASSUME CS:CODE,DS:DATA
MAIN    PROC  FAR;
    MOV    AX,DATA
    MOV    DS,AX
    ;此处输入代码段代码
    LEA    SI,BUF;       首地址;
    MOV    CX,COUNT;     个数;
    PUSH   SI;
    PUSH   CX;
    CALL   MINPROC;
    CALL   OUTPUT;


    MOV    AH,4CH;
    INT    21H;
;
寻找最小元素。  

MINPROC   PROC   NEAR
    LEA    DI,SAVEREG;
    MOV    [DI],AX;        ;save
    MOV    [DI+2],BX;
    MOV    [DI+4],CX;
    MOV    [DI+6],DX;
    POP    DX;            ;dx=ip
    pop cx;数组首地址;
    pop si;个数;
    PUSH   DX;
    xor al,al        ;al=0 如果没奇数,打印0
SEARCH:  

    MOV    DL,[SI];
    TEST   DL,01H;
    JZ     AA1;
    JMP    AA2;
AA1:
    CMP    DL,AL;
    ja     AA3;
    JMP    AA2;
AA3:
    MOV    AL,DL;    改变al
AA2:
    INC    SI;
    LOOP   SEARCH;
    MOV    AH,0;
    POP    CX;        ;cx=ip
    PUSH   AX;        ;save return value
  

    PUSH   CX;        ;save ip
  

  

    LEA    DI,SAVEREG
    MOV    AX,[DI];        ;restore
    MOV    BX,[DI+2];
    MOV    CX,[DI+4];
    MOV    DX,[DI+6];
RET
MINPROC  ENDP;
;
寻找最小元素函数结束

;最小元素存在栈区里,下面的函数为从栈中取元素,然后以16进制输出。
OUTPUT    PROC   NEAR;
    LEA    DI,SAVEREG;
    MOV    [DI],AX;
    MOV    [DI+2],BX;
    MOV    [DI+4],CX;
    MOV    [DI+6],DX;
    POP   AX;
    POP    BX;              最小元素在栈里
    PUSH  AX;
  

    MOV  CH,4;
    MOV  CL,4;

     

RLL:
    ROL  BX,CL;
    MOV  DL,BL;
     

    AND  DL,0FH;  

     

    ADD  DL,30H;
    CMP  DL,3AH;
    JB   SKIP;
    ADD  DL,7;
     

SKIP:

    MOV  AH,2;
    INT  21H;
    DEC  CH;
    JNZ  RLL;
  

  

  

    MOV  DL,'H';
    MOV  AH,2;
    INT  21H;
    LEA    DI,SAVEREG
    MOV    AX,[DI];
    MOV    BX,[DI+2];
    MOV    CX,[DI+4];
    MOV    DX,[DI+6];
RET
OUTPUT  ENDP;
;
16进制输出函数结束
MAIN   ENDP;
CODE   ENDS;
      END main
很久没写汇编了
楼主对堆栈理解得不错,但就错在了堆栈参数的传递上
小写的地方时我改的
楼主以前是写C的吧

没注意楼上已改好了。。。。


[ 本帖最后由 xiaomarn 于 2010-12-26 17:41 编辑 ]
#4
做个好人2010-12-26 22:11
谢谢楼上的几位,太感谢了.
#5
做个好人2010-12-26 22:12
回复 3楼 xiaomarn
呵呵,学完C,学C++,然后又开数据结构,现在又开算法基础和java.
#6
做个好人2010-12-26 22:36
回复 3楼 xiaomarn
您好.改完之后,为什么我最后 一行少了个main 结果就不一样了呢.
就是您的是end main
我的事end  结果就不一样了
#7
zaixuexi2010-12-26 22:57
不写END MAIN,编译器不知道你的入口地址,程序加载的时候并不一定是加载到0000H的(16位),你不写的话从0000H开始,一开始并没有执行你的代码,可能会顺序执行到你的代码,也可能被中断了,执行不到你的代码.
---------------------------------------------
可能说的不对,呵呵.

我是拿你的原来的代码直接上DEBUG看的.
1