| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1777 人关注过本帖
标题:一个三角X引发的“可视化”汇编编程
只看楼主 加入收藏
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用zklhp在2012-10-6 19:42:06的发言:

还有 其实这里主要是DOS的可视化 而非汇编的可视化。。。

恩 16位机范围比较窄 WIN32汇编才稍微接触点 不敢瞎写啦 希望别的坛友发点帖子说说这方面的心得啊。

梅尚程荀
马谭杨奚







                                                       
2012-10-06 20:18
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
好 下面一起来做两个数相加的程序吧
为了直观简单 我们假定a, b两数已经给定 并且直接给10进制数 而且根据C语言的int型范围 来做 超出这个范围的咱们先不做考虑
GO!------->
C程序及效果图:
程序代码:
#include <stdio.h>

int main(void)
{
    int a = 34724354, b = 19568435, sum; 

    sum = a + b;
    printf("The sum is %d \n", sum);    

    return 0;
}
--
图片附件: 游客没有浏览图片的权限,请 登录注册

现在用汇编来实现同样的目的。
汇编代码及效果图:
程序代码:
;#Mode=DOS
;MASMPlus
;--------------------------------------------------------------------
;--------------------------------------------------------------------
; program name:            AddTwoNumber
; producer:                yrjd
; program function:        Calculate the sum of two number and show it
; produce data:            2012-10-6  Saturday
;--------------------------------------------------------------------
assume cs:code, ds:data, ss:stack

stack segment
    db 128 dup(?)
stack ends

data segment
    aNumber        dd 34724354
    bNumber        dd 19568435
    rNumber        db 20 dup('$')
    rPrompt        db 'The sum is : ', '$'
    EndPrompt      db 'Press any key to continue', '$'
data ends

code segment
start:                  ; Segment register initialize 段寄存器初始化
                        mov    ax, stack
                        mov    ss, ax
                        mov    sp, 128                   

                        mov    ax, data
                        mov    ds, ax                   

                        ; deal with the add procedure 处理加法过程
                        mov    ax, WORD  ptr aNumber[0]
                        add    ax, WORD  ptr bNumber[0]
                        mov    dx, WORD  ptr aNumber[2]              
                        adc    dx, WORD  ptr bNumber[2]
                  
                        ; Get each bit digit 分解结果的各个位的数字
                        mov    si, 0
            GetBit:     mov    cx, 10
                        call   divdw
                        add    cx, 30h
                        push   cx
                        inc    si
                        cmp    ax, 0
                        jz     CmpAgain
                        jmp    GetBit
            CmpAgain:   cmp    dx, 0
                        jz     GetEnd
                        jmp    GetBit
            GetEnd:     mov    cx, si
                        mov    di, 0
            GetResult:  pop    ax
                        mov    rNumber[di], al
                        inc    di
                        loop   GetResult
                  
                        ; Prompt and Output the result  提示并输出结果
                        lea    dx, rPrompt
                        mov    ah, 09h
                        int    21h
                  
                        lea    dx, rNumber
                        mov    ah, 09h
                        int    21h
                  
                        call   crlf
                  
                        ; Output End Prompt 输出结束提示
                        lea    dx, EndPrompt
                        mov    ah, 09h
                        int    21h
                        
                        ; View the result and Return DOS 查看结果并返回DOS
                        mov    ah, 01h
                        int    21h
                        mov    ah, 4ch
                        int    21h
                  
                        ; The function of  Carriage-Return Line-Feed 回车换行
crlf:                   mov    dl, 0dh
                        mov    ah, 02h
                        int     21h
                        mov    dl, 0ah
                        mov    ah, 02h
                        int    21h
                        ret
                  
divdw:                ; not overflow  division   实施不溢出除法获取除10的余数
                        push    si
                        push    di
                        push    ax
                  
                        mov     ax, dx
                        mov     dx, 0
                        div     cx
                        mov     si, ax
                        pop     ax
                        div     cx
                        mov     cx, dx
                        mov     dx, si
                  
                        pop     di
                        pop     si
                  
                        ret
code ends

end start
--
图片附件: 游客没有浏览图片的权限,请 登录注册



[ 本帖最后由 有容就大 于 2012-10-6 21:33 编辑 ]

梅尚程荀
马谭杨奚







                                                       
2012-10-06 21:28
小习小习
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:蒙面侠
威 望:6
帖 子:1467
专家分:4792
注 册:2012-7-2
收藏
得分:0 
粗略的看书看到了第16章,对此我对大哥的代码只能看懂一些指令

实现自己既定的目标,必须能耐得住寂寞单干。
2012-10-06 22:56
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 13楼 小习小习
把那些检测点 和 课后实验都仔细过一遍 就能熟悉大部分指令了。

梅尚程荀
马谭杨奚







                                                       
2012-10-07 15:58
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
现在我们来做个两数相乘的程序 同样为了简单直观 只考虑乘积结果在int 范围之内 并直接给出这两数
GO!----->
C语言程序效果图:
图片附件: 游客没有浏览图片的权限,请 登录注册

汇编及其效果图:
程序代码:
;#Mode=DOS
;MASMPlus
;--------------------------------------------------------------------
;--------------------------------------------------------------------
; program name:            MulTwoNumber
; producer:                yrjd
; program function:        Calculate the Product of two number and show it
; produce data:            2012-10-7  Sunday
;--------------------------------------------------------------------
assume cs:code, ds:data, ss:stack

stack segment
    db 128 dup(?)
stack ends

data segment
    aNumber        dw 14533
    bNumber        dw 34530
    rNumber        dw 20 dup('$')
    rPrompt        db 'The result is : ', '$'
    EndPrompt      db 'Press any key to continue', '$'
data ends

code segment
start:                  ; Segment register initialize 段寄存器初始化
                        mov    ax, stack
                        mov    ss, ax
                        mov    sp, 128                

                        mov    ax, data
                        mov    ds, ax                 

                        ; deal with the add procedure 处理加法过程
                        ; 两个数相乘 可以拆分成加法 也可以直接相乘                      

;-----------------------------------------------------------------
; 此为分解成加法的过程
;                        mov    cx, aNumber
;                        mov      ax, 0
;                        mov      dx, 0
;            AddLoop:    add    ax, WORD  ptr bNumber[0]
;                        adc    dx, 0
;                        loop      AddLoop       

;------------------------------------------------------------------                      
;------------------------------------------------------------------
; 此为直接相乘
                         mov    ax, aNumber
                         mov    dx, 0
                         mov    cx, bNumber
                         mul     cx
;------------------------------------------------------------------                

                        ; Get each Decimal digit 分解结果的各个位的数字
                        mov    si, 0
            GetDec:     mov    cx, 10
                        call   divdw
                        add    cx, 30h
                        push   cx
                        inc    si
                        cmp    ax, 0
                        jz     CmpAgain
                        jmp    GetDec
            CmpAgain:   cmp    dx, 0
                        jz     GetEnd
                        jmp    GetDec
            GetEnd:     mov    cx, si
                        mov    di, 0
            GetResult:  pop    ax
                        mov    BYTE ptr rNumber[di], al
                        inc    di
                        loop   GetResult
                
                        ; Prompt and Output the result  提示并输出结果
                        lea    dx, rPrompt
                        mov    ah, 09h
                        int    21h
                
                        lea    dx, rNumber
                        mov    ah, 09h
                        int    21h
                
                        call     crlf
                
                        ; Output End Prompt 输出结束提示
                         lea    dx, EndPrompt
                         mov    ah, 09h
                         int    21h
                      
                        ; View the result and Return DOS 查看结果并返回DOS
                        mov    ah, 01h
                        int    21h
                        mov    ah, 4ch
                        int    21h
                
                        ; The function of  Carriage-Return Line-Feed 回车换行
crlf:                   mov    dl, 0dh
                        mov    ah, 02h
                        int     21h
                        mov    dl, 0ah
                        mov    ah, 02h
                        int    21h
                        ret                 

divdw:                ; not overflow  division   实施不溢出除法获取除10的余数
                        push     si
                        push    di
                        push    ax
                
                        mov    ax, dx
                        mov    dx, 0
                        div    cx
                        mov    si, ax
                        pop    ax
                        div    cx
                        mov    cx, dx
                        mov    dx, si
                
                        pop    di
                        pop    si
                
                        ret
code ends

end start
---
图片附件: 游客没有浏览图片的权限,请 登录注册


在这个汇编程序中有两种方法 1 分解成数个加法, 2 直接用汇编的Mul指令
这里俺有个疑问 :mul指令比add指令要耗时的多  ,当两个相乘的数较小时 分解成加法
循环次数少比较占优势 那么当两个数比较大时 用mul指令好还是用add指令好?
mul指令在计算机中的运作方式又是怎样的呢? 是不是计算机也将mul指令拆分成数个add/adc指令
只是对我们来说是不可见的?


梅尚程荀
马谭杨奚







                                                       
2012-10-07 16:09
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
上面的程序都是给定两个数后 才进行计算
下面我们做一个提示输入两个数后 再计算的程序
先看C语言程序及两种结果图:
图片附件: 游客没有浏览图片的权限,请 登录注册

————
直接上汇编代码:
程序代码:
;#Mode=DOS
;MASMPlus 单文件代码模板 - 纯 DOS 程序
;--------------------------------------------------------------------
;--------------------------------------------------------------------
; program name:                AddTwoNum
; producer:                    yrjd
; program function:            Calculate the sum of  two number and show it
; produce data:                2012-10-7     Sunday
;--------------------------------------------------------------------
assume cs:code, ds:data, ss:stack

stack segment
    db    128 dup (?)
stack ends

data segment
NumberA        db 80
        LenA   db ?
        ActA   db 80 dup (0)
NumberB        db 80
        LenB   db ?
        ActB   db 80 dup (0)
NumberR        dw 0, 0, 0, 0, 0, 0      
StringR        db    80 dup ('$')
PromptA        db 'Please input Number a: ', '$'
PromptB        db 'Please input Number b: ', '$'
PromptR        db 'The sum of a and b is: ', '$'
PromptEnd      db 'Press any key to continue', '$'
data ends

code segment
START:             ;; Segment register initialize 段寄存器初始化
                    mov    ax, stack
                    mov    ss, ax
                    mov    sp, 128
                    mov    ax, data
                    mov    ds, ax                   

                    ;; Prompt input number a   提示输入a
                    lea    dx, PromptA
                    mov    ah, 09h
                    int    21h
                  
                    ;; Input a and set into NumberA 输入a并放置在NumberA中
                    lea    dx, NumberA
                    mov    ah, 0ah
                    int    21h                                 

                    call   CRLF
                 
                    ;; Convert the string to decimal number 把数字字符串转换为十进制数
                    mov    cl, LenA
                    mov    ch, 0
                    mov    ax, 0
                    mov    dx, 0
                    lea    si, ActA
                    add    si, cx
                    dec    si
                    mov    di, 0
    ConvertA:       push   cx
                    sub    [si], 30h
                    mov    al, BYTE ptr [si]
                    mov    ah, 0
                    mov    dx, 0
                    cmp    di, 0
                    jz     SingleA
                    mov    bx, 10
                    mov    cx, di                   

    MulTenA:        mul    bx
                    loop   MulTenA
    SingleA:        add    NumberR[0], ax
                    adc    NumberR[2], dx
                    dec    si
                    pop    cx
                    inc    di
                    loop    ConvertA
                  
                    ;; Prompt input number b   提示输入b
                    lea    dx, PromptB
                    mov    ah, 09h
                    int    21h                  

                    ;; Input a and set into NumberB 输入a并放置在NumberB中
                    lea    dx, NumberB
                    mov    ah, 0ah
                    int    21h                  

                    call     CRLF
                  
                    ;; Convert the string to decimal number 把数字字符串转换为十进制数
                    mov    cl, LenB
                    mov    ch, 0
                    mov    ax, 0
                    mov    dx, 0
                    lea    si, ActB
                    add    si, cx
                    dec    si       

                    mov    di, 0
    ConvertB:       push   cx
                    sub    [si], 30h
                    mov    al, BYTE ptr [si]
                    mov    ah, 0
                    mov    dx, 0
                    cmp    di, 0
                    jz     SingleB
                    mov    bx, 10
                    mov    cx, di
    MulTenB:        mul    bx
                    loop   MulTenB
    SingleB:        add    NumberR[4], ax
                    adc    NumberR[6], dx
                    dec    si
                    pop    cx
                    inc    di
                    loop    ConvertB                              

                    ; Add the two Converted Decimal number
                    ; 把转换的两个十进制数加起来放在ax, dx中
                    mov    ax, NumberR[0]
                    add    ax, NumberR[4]
                    mov    dx, NumberR[2]
                    adc    dx, NumberR[6]
                  
                    ; Get each point number 分解结果的各个位的数字
                    mov    si, 0

 GetEachNum:        mov    cx, 10
                    call   divdw
                    add    cx, 30h
                    push   cx
                    inc    si          
                    cmp    ax, 0
                    jz     CmpAgain
                    jmp    GetEachNum
   CmpAgain:        cmp    dx, 0
                    jz     GetEnd
                    jmp    GetEachNum
   GetEnd:          mov    cx, si
                    mov    di, 0
   GetResult:       pop    ax
                    mov    StringR[di], al
                    inc    di
                    loop   GetResult                  

                    ;; Prompt the result's output 提示并输出结果
                    lea    dx, PromptR
                    mov    ah, 09h
                    int    21h
                  
                    lea    dx, StringR
                    mov    ah, 09h
                    int    21h
                  
                    call    CRLF                   

                    ; Output End Prompt 输出结束提示
                    lea    dx, PromptEnd
                    mov    ah, 09h
                    int    21h
                       
                    ; View the result and Return DOS 查看结果并返回DOS
                    mov    ah, 01h
                    int    21h
                    mov    ah, 4ch
                    int    21h                  
                      
                    ;; The function of Carriage-Return Line-Feed 回车换行函数
CRLF:                push   ax
                     push   dx
                  
                     mov    dl, 0dh
                     mov    ah, 02h
                     int    21h
                     mov    dl, 0ah
                     mov    ah, 02h
                     int    21h
                  
                     pop    dx
                     pop    ax
                     ret                      

divdw:               ; not overflow  division   实施不溢出除法获取除10的余数
                     push    si
                     push    di
                     push    ax               

                     mov     ax, dx
                     mov     dx, 0
                     div     cx
                     mov     si, ax
                     pop     ax
                     div     cx
                     mov     cx, dx
                     mov     dx, si
                
                     pop     di
                     pop     si              
                     ret                  
code ends

end START
这个方法的大概构思就是将两个字符串转换为两个十进制数后相加 在显示出来
由于在转换的过程中有个循环相乘溢出的问题 所以相加的两数被限制在6位以内
看看以后能不能解决这个问题。到时候再详细研究下。


如果不用这个方法直接按位    处理BCD码和字符的转换 请参考 我写的那个大数相加的程序
这里就不重复了。https://bbs.bccn.net/thread-382463-1-1.html


[ 本帖最后由 有容就大 于 2012-10-7 22:58 编辑 ]

梅尚程荀
马谭杨奚







                                                       
2012-10-07 22:56
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以前我们的程序都没涉及负数 这次做一个排序的程序 且能处理负数。
看C代码及效果图:
图片附件: 游客没有浏览图片的权限,请 登录注册

我们用汇编来实现 这里的关键是判断负数和显示负数:
程序代码:
;#Mode=DOS
;MASMPlus
;--------------------------------------------------------------------
;--------------------------------------------------------------------
; program name:            Sort
; producer:                yrjd
; program function:        Sort a series of numbers and show it
; produce data:            2012-10-11  Thursday
;--------------------------------------------------------------------
assume cs:code, ds:data, ss:stack

stack segment para stack 'stack'
  db    30 dup (?)
stack ends

data segment
NumArray     dw 56, 57, 4767, 4, 543, 76, 44, 0fffch, 0eefch, 0
Index        dw ?
NumString    db 128 dup('$')
rPrompt      db 'The sum is : ', '$'
EndPrompt    db 'Press any key to continue', '$'
data ends

code segment
start:                  ; Segment register initialize 段寄存器初始化
                        mov    ax, stack
                        mov    ss, ax
                        mov    sp, 30              
                        mov    ax, data
                        mov    ds, ax                       

                        ; Sort 排序
                        mov     cx, 9
                        mov    si, 0
                Sort:   mov    bx, NumArray[si]
                        mov    di, si
                        mov    Index, si
                        add    di, 2
            InSort:     cmp    di, 18
                        ja    GetSingle
                        cmp    bx, NumArray[di]
                        jng     Ctnu
                        mov    bx, NumArray[di]
                        mov    ax, di
                        mov    Index, ax
                Ctnu:   add    di, 2
                        jmp    InSort
           GetSingle:   push    di
                        mov    di, Index
                        push    NumArray[si]
                        push    NumArray[di]
                        pop    NumArray[si]
                        pop    NumArray[di]
                        pop    di
                        push    NumArray[si]
                        add    si, 2
                        loop    Sort      
                        push    NumArray[si]
          
                        mov    cx, 10
                        mov    di, 0          
    StoreString:        mov    dx, 0
                        pop    ax
                        call    dis
                        loop    StoreString
              
                        ; Prompt and Output the result  提示并输出结果
                        lea    dx, rPrompt
                        mov    ah, 09h
                        int    21h
               
                        lea    dx, NumString
                        mov    ah, 09h
                        int    21h
                
                        call   crlf
              
                        ; Output End Prompt 输出结束提示
                        lea    dx, EndPrompt
                        mov    ah, 09h
                        int    21h
                      
                        ; View the result and Return DOS 查看结果并返回DOS
                        mov    ah, 01h
                        int    21h
                        mov    ah, 4ch
                        int    21h   

dis:          
                        push    bx
                        push    cx
                        push    dx
                        push    si
                        push    ax

                        ; Judge negative     判断是不是负数
                        mov    bx, ax
                        cmp    ax, 0
                        jnl    Positive
                        mov    cx, 0ffffh
                        sub    cx, ax
                        inc    cx
                        mov    ax, cx
                        ; Get each bit digit 分解结果的各个位的数字
            Positive:   mov    si, 0
            GetBit:     mov    cx, 10
                        call   divdw
                        add    cx, 30h
                        push   cx
                        inc    si
                        cmp    ax, 0
                        jz     CmpAgain
                        jmp    GetBit
            CmpAgain:   cmp    dx, 0
                        jz     GetEnd
                        jmp    GetBit
            GetEnd:     cmp    bx, 0
                        jnl    Positive1
                        mov    bl, '-'
                        mov    bh, 0
                        push   bx
                        inc    si
            Positive1:  mov    cx, si
            GetResult:  pop    ax
                        mov    NumString[di], al
                        inc    di
                        loop   GetResult                       

                        mov    al, ' '
                        mov    NumString[di], al
                        inc    di                      

                        pop    ax                      
                        pop    si
                        pop    dx
                        pop    cx
                        pop    bx
                        ret
                                         
                       ; The function of  Carriage-Return Line-Feed 回车换行
crlf:                   mov    dl, 0dh
                        mov    ah, 02h
                        int     21h
                        mov    dl, 0ah
                        mov    ah, 02h
                        int    21h
                        ret                 

divdw:                ; not overflow  division   实施不溢出除法获取除10的余数
                        push    si
                        push    di
                        push    ax
                
                        mov     ax, dx
                        mov     dx, 0
                        div     cx
                        mov     si, ax
                        pop     ax
                        div     cx
                        mov     cx, dx
                        mov     dx, si                 

                        pop     di
                        pop     si                
                        ret           

code ends
end start

图片附件: 游客没有浏览图片的权限,请 登录注册



[ 本帖最后由 有容就大 于 2012-10-11 15:10 编辑 ]

梅尚程荀
马谭杨奚







                                                       
2012-10-11 15:05
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
还是完成一个作业先  实现查找功能 可以实现负数的查找
看C的代码和效果图:
图片附件: 游客没有浏览图片的权限,请 登录注册

再上汇编的:

图片附件: 游客没有浏览图片的权限,请 登录注册

--
程序代码:
;#Mode=DOS
;MASMPlus
;--------------------------------------------------------------------
;--------------------------------------------------------------------
; program name:            Search
; producer:                yrjd
; program function:        Search a number in an array
; produce data:            2012-10-12  Friday
;--------------------------------------------------------------------
assume cs:code, ds:data, ss:stack

stack segment para stack 'stack'
  db    128 dup (?)
stack ends

data segment
NumArray      dw 0ffd3h, 75, 9877, 43, 0fffdh, 0, 653, 776, 41a1h, 666
SearchNum     db 32
    NumLen    db ?
    ActNum    db 32 dup (?)
InputPrompt   db 'Please input the Number you want to search: ', '$'
NotFound      db 'Can not find the number!', '$'
HasFound      db 'It has found the number!', '$'
EndPrompt     db 'Press any key to continue', '$'
data ends

code segment
start:                  ; Segment register initialize 段寄存器初始化
                        mov    ax, stack
                        mov    ss, ax
                        mov    sp, 128              
                        mov    ax, data
                        mov    ds, ax                  

            ; Prompt and Input the search number  提示并输入要查找的数
                        lea     dx, InputPrompt
                        mov     ah, 09h
                        int     21h
                        lea    dx, SearchNum
                        mov    ah, 0ah
                        int    21h
                     
                        call    ConvertToHex
                     
                      ; Compare and show the result
                      ; 比较并输出结果
                      mov    cx, 10
                      mov    si, 0
                      mov    al, 0
        SearchFor:    cmp    di, NumArray[si]
                      jz    AddCount
             next:    add    si, 2
                      jmp    s
         AddCount:    inc    al
                      add    si, 2
            s:        loop    SearchFor
                           
                      call   crlf
           
                      cmp    al, 0
                      jz    CannotFound
                      lea    dx, HasFound
                      mov    ah, 09h
                      int    21h
                      jmp    OK
      CannotFound:    lea    dx, NotFound
                      mov    ah, 09h
                      int     21h           
         
                      ; Output End Prompt 输出结束提示
         OK:          call    crlf
                      lea    dx, EndPrompt
                      mov    ah, 09h
                      int    21h
                       
                      ; View the result and Return DOS 查看结果并返回DOS
                      mov    ah, 01h
                      int    21h
                      mov    ah, 4ch
                      int    21h
           
                      ; The function of  Carriage-Return Line-Feed 回车换行
crlf:                  push    ax
                       push    dx
                       mov     dl, 0dh
                       mov     ah, 02h
                       int     21h
                       mov     dl, 0ah
                       mov     ah, 02h
                       int     21h
                       pop    dx
                       pop    ax
                       ret
   
                      ; Convert the string to a Hex number 把输入的字符串转化为十六进制数 
 ConvertToHex:        push    ax
                      push    bx
                      push    cx
                      push    dx
                      push    si
           
                      mov    cl, NumLen
                      mov    ch, 0           
                      mov    si, 0
                      cmp    BYTE ptr ActNum[si], '-'
                      jnz    PushBCD
                      dec    cl
                      mov    si, 1
          PushBCD:    mov    dl, BYTE ptr ActNum[si]
                      sub    dl, 30h
                      mov    dh, 0
                      push    dx
                      inc    si
                      loop    PushBCD
           
                      mov    cl, NumLen
                      mov    ch, 0
                      mov    bx, 10
                      mov    si, 0   
                      mov    di, 0
                      cmp    BYTE ptr ActNum[0], '-'
                      jnz    GetHex
                      dec    cl
       GetHex:        pop    ax
                      push    cx
                      cmp    si, 0
                      jz    AddEach
                      mov    cx, si
       MulTen:        mov    dx, 0
                      mul    bx
                      loop    MulTen
          AddEach:    add    di, ax
                      inc    si
                      pop    cx
                      loop    GetHex
           
                      cmp    BYTE ptr ActNum[0], '-'
                      jnz    ConvertOK
                      mov    ax, 65535
                      sub    ax, di
                      inc    ax
                      mov    di, ax
           
        ConvertOK:    pop    si
                      pop    dx
                      pop    cx
                      pop    bx
                      pop    ax
                      ret
code ends

end start

梅尚程荀
马谭杨奚







                                                       
2012-10-13 14:23
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
判断一个年份是否是闰年 范围公元1-9999
程序代码:
;#Mode=DOS
assume cs:code, ds:data, ss:stack

stack    segment para 'stack'
             db    128 dup (?)
stack    ends

data    segment
EndPrompt    db 'Press any key to continue...', '$'
InputPrompt  db 'Please input the year:', '$'
IsLeapYear   db 'This is a leap year!', '$'
NotLeapYear  db 'This is not a leap year!', '$'
AskContinue  db 'Do you want to continue?(Y/N):', '$'
YearString   db 10
    YSLen    db ?
    YSAct    db 10 dup ('$')
YearValue    dw 0
data    ends

code     segment
start:        ;; Initialize the segment register 段寄存器初始化
              mov    ax, stack
              mov    ss, ax
              mov    sp, 128
              mov    ax, data
              mov    ds, ax
      
              ;; Prompt user to input a year 提示用户输入一个年份
InputYear:    mov    dx, offset InputPrompt
              mov    ah, 09h
              int    21h      
      
              ;; Input a year as string  以字符串形式输入年份
              lea    dx, YearString
              mov    ah, 0ah
              int    21h          

              call    CheckYear
              call    crlf
              cmp    ax, 0
              je    InputYear              

              mov    YearValue[0], 0
              call     ConvertStr      
              call    JudgeLeap    
              call     crlf       

              ;; Ask the user whether to continue
              ;; 询问是否继续
              lea    dx, AskContinue
              mov    ah, 09h
              int    21h
              ;; Input the choice
              ;; 输入你的选择
              mov    ah, 01h
              int    21h
              call     crlf
              cmp    al, 'Y'
              je    InputYear
      
              ;; Prompt end and return 程序结束并返回
              mov    dx, offset EndPrompt
              mov    ah, 09h
              int    21h
              mov    ah, 01h
              int    21h
              mov    ah, 4ch
              int    21h
      
crlf:         ;;  Carriage-Return Line-Feed 回车换行
              push    dx
              push    ax
              mov    dl, 0dh
              mov    ah, 02h
              int    21h
              mov    dl, 0ah
              mov    ah, 02h
              int    21h
              pop    ax
              pop    dx
              ret
      
              ;; Check the legitimacy of the input (inside four number characters)
              ;; 检查输入的合法性(在四个数字字符内)
CheckYear:    push    cx
              push    si
              cmp    YSLen, 4
              ja    InputError
              mov    cl, YSLen
              mov    ch, 0
              mov    si, 0

 CheckNum:    cmp    byte ptr YSAct[si], '0'
              jb    InputError
              cmp    byte ptr YSAct[si], '9'
              ja    InputError
              inc    si
              loop    CheckNum
              mov    ax, 1
              jmp    CheckEnd
InputError:   mov    ax, 0

 CheckEnd:    pop    si
              pop    cx
              ret
          
              ;; COnvert the Year's string to Year's Value
              ;; 把年份的字符串转换为数值
ConvertStr:   push    ax
              push    bx
              push    cx
              push    dx
              push    si
              push    di
      
              mov    cl, YSLen
              mov    ch, 0
              mov    si, cx
              dec    si
              mov    di, 0
              mov    bx, 10       


 DealEach:    push    cx
              mov    al, BYTE ptr YSAct[si]
              sub    al, 30h
              mov    ah, 0
              mov    dx, 0
              cmp    di, 0
              je    AddEach
              mov    cx, di          
    MulTen:   mul    bx
              loop    MulTen
  AddEach:    add    YearValue[0], ax
              dec    si
              inc    di
              pop    cx
              loop    DealEach
          
              pop    di
              pop    si
              pop    dx
              pop    cx
              pop    bx
              pop    ax
              ret
     
JudgeLeap:    ;; Judge whether is the leap year
              ;; 判断是否为闰年      
              push    ax
              push    bx
              push    cx
              push    dx
              push    si
              push    di
     
              mov    ax, YearValue[0]
              mov    dx, 0
              mov    bx, 4
              div    bx
              cmp    dx, 0
              jne    NotLeap
              mov    ax, YearValue[0]
              mov    dx, 0
              mov    bx, 100
              div    bx
              cmp    dx, 0
              je    Div400
              lea    dx, IsLeapYear
              mov    ah, 09h
              int    21h
              jmp    OK
    Div400:   mov    ax, YearValue[0]
              mov    dx, 0
              mov    bx, 400
              div    bx
              cmp    dx, 0
              jne    NotLeap
              lea    dx, IsLeapYear
              mov    ah, 09h
              int    21h
              jmp    OK
  NotLeap:    lea    dx, NotLeapYear
              mov    ah, 09h
              int    21h
    OK:       pop    di
              pop    si
              pop    dx
              pop    cx
              pop    bx
              pop    ax
              ret
code    ends

end    start
图片附件: 游客没有浏览图片的权限,请 登录注册


梅尚程荀
马谭杨奚







                                                       
2012-10-26 12:54
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11774
专家分:43421
注 册:2006-5-13
收藏
得分:0 
请问楼主汇编可视化是用什么软件做到的?

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-10-26 14:28
快速回复:一个三角X引发的“可视化”汇编编程
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.063281 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved