| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1777 人关注过本帖
标题:一个三角X引发的“可视化”汇编编程
取消只看楼主 加入收藏
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
结帖率:99.34%
收藏
已结贴  问题点数:20 回复次数:13 
一个三角X引发的“可视化”汇编编程
写了那个杨辉三角 我就想能不能用汇编去表达一下C语言呢
或者通过对C语言的翻译来学习汇编呢
先发一些简单的吧
本人系自学初学 很多东西不明白 只能看到一些表面上的东西 很多原理性的东西还弄不清楚
发这个贴为的是大家讨论 希望新手有所收获 更希望大牛多给指导

那我们从Hello World!开始吧
在C语言中程序和效果图如下
程序代码:
#include <stdio.h>

int main(void)
{
    char str[128];

    printf("Please input a string: ");
    gets(str);
    puts(str);

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

现在我们就用汇编来达到这个目的
楼主还看不懂反汇编代码 这个的反汇编代码光是个int 3就有无数个 嘎嘎
我们只是简单的实现与C程序同样的功能就OK了吧 呵呵
汇编的代码就效果图
程序代码:
;#Mode=DOS
;MASMPlus 单文件代码模板 - 纯 DOS 程序
;;; 很遗憾DOS不支持中文字符串? 大牛们有什么办法吗?
assume cs:code, ds:data, ss:stack

stack segment
    db 128 dup(?)
stack ends

data segment
    PutStr           db 'Please input a string: ', '$'
    OutStr           db 128
        OutLen       db ?
        ActualStr    db 128 dup ('$')
    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
                  
                    ; Input prompt 输入提示
                    lea    dx, PutStr
                    mov    ah, 09h
                    int    21h
                  
                    ; begin Input string and Output it 开始输入字符串并显示出来
                    lea    dx, OutStr
                    mov    ah, 0ah
                    int     21h              
                
                    ; Set the Cursor 2 row 23 column 设置光标于2行23列
                    mov    ah, 02h
                    mov    bh, 0
                    mov    dh, 2
                    mov    dl, 23
                    int    10h                   

                    ; Output it 显示输入字符串
                    lea     dx, ActualStr
                    mov    ah, 09h
                    int    21h
                  
                    ; Carriage-Return Line-Feed 回车换行
                    call    crlf
                  
                    ; Set Cursor in 3 row 0 column 光标置于3行0列
                    mov    ah, 02h
                    mov    bh, 0
                    mov    dh, 3
                    mov    dl, 0
                    int    10h
                  
                    ; 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
code ends

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

看吧 其实没有什么汇编基础只要知道几个指令的功能 寄存器的作用 及不到4个中断功能
就能实现这个目的 以前对汇编存有极大的恐惧 迟迟不敢下手 看来是不应该的啦 呵呵。
有兴趣的朋友可以看下 并指出其中的不足 给出更好的方法。。。
搜索更多相关主题的帖子: C语言 include 杨辉三角 东西 
2012-10-06 15:52
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用信箱有效在2012-10-6 16:59:29的发言:

接分  不速结贴不是好唐僧

速发帖 不速发不是好快递。

梅尚程荀
马谭杨奚







                                                       
2012-10-06 17:12
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 2楼 小习小习
一起学习 嘿嘿


梅尚程荀
马谭杨奚







                                                       
2012-10-06 17:17
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用信箱有效在2012-10-6 17:17:56的发言:

不接分的好快递绝对不是厨师中的好司机。

晕倒

梅尚程荀
马谭杨奚







                                                       
2012-10-06 18:59
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用zklhp在2012-10-6 19:40:27的发言:

没赶上、、

DOS支持中文字符串一般是用字库 研究这个没啥意思了

我觉得可以加精华各位觉得呢 是原创的罢。。

谢谢Z版鼓励啊 我后面还会继续加些东西 望多多给俺撑腰啊(模糊的地方就靠你啦) 呵呵

梅尚程荀
马谭杨奚







                                                       
2012-10-06 20:16
有容就大
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: 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
快速回复:一个三角X引发的“可视化”汇编编程
数据加载中...
 
   



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

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