首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对设置位进行计数。16位汇编奇偶校验程序

对设置位进行计数。16位汇编奇偶校验程序
EN

Stack Overflow用户
提问于 2011-10-15 06:52:09
回答 1查看 1.6K关注 0票数 2

我正在尝试编写一个子过程,它将计数16位数字中设置的buts数,然后将该数字(设置的位数)发送回AX中的主过程。main应显示1的数量,并确定该数字是偶数还是奇数。

我试图通过向左移位并在进位时递增来计算1。问题似乎是,当我返回到“main”时,原始输入数字仍在AX中,而不是我在“parity.”中获得的计数。我不知道为什么它不会改变。

代码语言:javascript
复制
    ;===================================================================
    ;                   MAIN.ASM
    ;===================================================================
         EXTERN  GETDEC$:FAR
         EXTERN  NEWLINE:FAR
         EXTERN  PUTSTRNG:FAR
         EXTERN  PUTDEC$:FAR
         EXTERN  PUTBIN:FAR
         EXTERN  PARITY:FAR
    ;===================================================================
        .MODEL  LARGE
        .STACK  512
    ;===================================================================
    ; D A T A   S E G M E N T   D E F I N I T I O N
        .DATA
    NUMBER      DW  ?
    PROMPT      DB 'Enter a number: '
    BINDISPLAY      DB 'Number in binary: '
    ONESDISPLAY     DB 'Number of 1s: '
    ODDDISPLAY      DB 'The number of 1s is odd. '
    EVENDISPLAY DB 'The number of 1s is even. '  
    ;===================================================================
    ; C O D E   S E G M E N T   D E F I N I T I O N
        .CODE
            ASSUME  DS:DGROUP
    ;===================================================================

    MAIN    PROC

        MOV     AX,DGROUP           ;SET DS-REGISTER TO POINT TO
        MOV     DS,AX               ;DATA SEGMENT
        MOV     ES,AX               ;AND ES ALSO

        CALL    NEWLINE
        MOV     DI, OFFSET PROMPT
        MOV     CX, SIZEOF PROMPT
        CALL    PUTSTRNG
        CALL    GETDEC$
        CALL    NEWLINE
        MOV     DI, OFFSET BINDISPLAY
        MOV     CX, SIZEOF BINDISPLAY
        CALL    PUTSTRNG 
    CALL    PUTBIN
        PUSH    AX
        CALL    PARITY 
    CALL    NEWLINE


        CALL    NEWLINE
        MOV     DI, OFFSET ONESDISPLAY
        MOV     CX, SIZEOF ONESDISPLAY
        CALL    PUTSTRNG
    POP AX
        CALL    PUTDEC$
        CALL    NEWLINE

    SUB DX, DX
        MOV     BX, 2
        DIV     BX
        CMP     DX, 0
        JNE     ODDS

        MOV     DI, OFFSET EVENDISPLAY
        MOV     CX, SIZEOF EVENDISPLAY
        CALL    NEWLINE
        CALL    PUTSTRNG
        JMP     EXIT_PROGRAM
ODDS:    
        MOV     DI, OFFSET ODDDISPLAY
        MOV     CX, SIZEOF ODDDISPLAY
        CALL    NEWLINE
        CALL    PUTSTRNG       
EXIT_PROGRAM:
    .EXIT
        MOV     AX, 4C00H
        INT     21H
MAIN    ENDP
        END MAIN

;;===================================================================
;              Veronica Kaufman
;                 CISP 310
;                PARITY.ASM
;===================================================================
         .MODEL  LARGE     
;===================================================================
; D A T A   S E G M E N T   D E F I N I T I O N
        .DATA 
ONES_COUNT     DW      0                           
;===================================================================
; C O D E   S E G M E N T   D E F I N I T I O N
        .CODE   
        ASSUME  DS:DGROUP
;===================================================================

PARITY  PROC    FAR PUBLIC USES CX DX DS
    POP AX
NUM_LOOP:
    CMP AX, 0
    JE  END_PROGRAM
    SHL AX, 1
    JC  INCREMENT
    JMP NUM_LOOP
INCREMENT:
    INC ONES_COUNT
    JMP NUM_LOOP
END_PROGRAM:
    MOV AX, ONES_COUNT  
    PUSH    AX
    RET
PARITY  ENDP
        END PARITY
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-10-15 07:43:51

我假设这样做的目的是PARITY将在堆栈上接受一个参数,然后修改该参数,将其保留在堆栈上的相同位置:

代码语言:javascript
复制
; (This does not work, see below)

...
    PUSH    AX          ; input value
    CALL    PARITY      ; want this to change it in-place...
    ...
    POP     AX          ; ...so that this pops off the output value
    CALL    PUTDEC$

...

PARITY  PROC    FAR PUBLIC USES CX DX DS
    POP     AX          ; get argument from stack
    ...
    PUSH    AX          ; put result back on stack
    RET

这是行不通的,原因有两个:

  1. CALL将返回地址推送到堆栈上。
  2. PROC ... USES生成的开场白代码将更多内容推送到堆栈上。

当您在PARITY内部执行POP AX时,您实际上是在弹出一些完全不同的东西(然后将其他东西放回原来的位置)--可能是由PARITY保存的其他寄存器之一。

正确做这件事的选择:

如果您理解这里使用的调用约定,您应该能够找到推送到堆栈上的AX的位置,很可能是在距离BP寄存器很小的偏移处(我对

  • 还不够熟悉,无法确切地知道在这种情况下PROC-generated序号代码是做什么的),并加载/存储它,使PARITY直接接受其输入并将其输出返回到AX寄存器中。在这种情况下,您需要删除CALL PARITY之前的PUSH AX (输入已经在AX中),并将其直接放在CALL之后(保存返回结果,稍后将弹出-我假设需要保存AX,因为它可能被其他调用破坏);并从PARITY.

中删除POP AXPUSH AX

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7774390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档