zoukankan      html  css  js  c++  java
  • 第一个x86汇编程序

    我们在学习每一门编程语言时都会习惯性地吧helloworld作为第一个程序,汇编也不例外,然而,博主却遇到了一个小小的难题,并在同学的帮助下解决,现写随笔做记录。

    原hello.asm程序代码

    data segment
    string db  ;hello,assembly!',0dh,0ah,24h
    data ends
    
    code segment
    assume cs:code,ds:data
    start:
            mov bx,offset string
            mov di,00
    again:
            mov dl,[bx+di]
            cmp  dl,'$'
            jz     done
            mov  ah,02h
            int     21h
            inc    di
           jmp   again
    done:
            mov  ah,4ch
            int     21h
    code  ends
    end   start            

    这个代码在使用MASM编译和链接的时候都是一切正常的,然而在真正执行时,出现了一堆乱码。

    我很郁闷,于是在学习群里问大佬,大佬回答道:你试试这样:

    在start:下面紧跟着写一个

    mov  ax,data

    mov  ds,ax

    于是代码变成了这样

    更改后的hello.asm 代码

    data segment
    string db  ;hello,assembly!',0dh,0ah,24h
    data ends
    
    code segment
    assume cs:code,ds:data
    start:
            mov  ax,data
            mov  ds,ax
            mov bx,offset string
            mov di,00
    again:
            mov dl,[bx+di]
            cmp  dl,'$'
            jz     done
            mov  ah,02h
            int     21h
            inc    di
           jmp   again
    done:
            mov  ah,4ch
            int     21h
    code  ends
    end   start        

    上图中标红加粗的就是改的地方了,这里是把数据段段的地址位置data的值赋给了数据段寄存器ds

    看似很简单的一个mov 操作

    但是ds的地址就被改成了当前设置的data

    所以才不会出现之前的乱码

    我猜想原因应该是:

    未进行mov  ax,data   mov   ds,ax 赋值之前,ds的值是0,而data的段地址并不是0

    只有在赋值后,ds和data才能统一,通过ds来访问数据段才能得到正确的结果

    这里提及了两个概念,即代码段和代码段寄存器

    首先是段的概念

    我们编写的程序分为3个段

    堆栈段stack segment

    数据段data   segment

    代码段code  segment

    这三个段中,只有code  segment是必须的

    所以,在我写的helloworld程序中,我只用了data和code两个段

    data段我用来存放数据

    code段是具体的x86汇编代码

    段寄存器是什么

    The 6 Segment Registers are:

    • Stack Segment (SS). Pointer to the stack.
    • Code Segment (CS). Pointer to the code.
    • Data Segment (DS). Pointer to the data.
    • Extra Segment (ES). Pointer to extra data ('E' stands for 'Extra').
    • F Segment (FS). Pointer to more extra data ('F' comes after 'E').
    • G Segment (GS). Pointer to still more extra data ('G' comes after 'F').

    参考自X86 Assembly/X86 Architecture - Wikibooks, open books for an open world

    上面引用的资料表明,data  segment段寄存器是一个指向数据段的指针

    哦,指针

    想必同学们会大吃一惊,

    指针不初始化,结果就是乱码,这个应该就好理解多了吧。

    所以,用mov  ax,data   mov   ds,ax 进行指针初始化,就能够使得最后的结果可以完美输出

    在这里我再一次感谢学习中帮助过我的人,好人一生平安!

    语言表达能力有限,有不足之处,还望读者斧正。

    本文完.

  • 相关阅读:
    面向对象(Object Oriented)
    文件操作
    函数
    dict--字典
    list--列表
    Ubuntu_18.04安装网易云音乐
    初识数据类型
    css控制内容显示,自动加"..."
    css固定元素位置(fixed)
    解决IE下iframe默认有白色背景的bug
  • 原文地址:https://www.cnblogs.com/studentWangqy/p/12590210.html
Copyright © 2011-2022 走看看