zoukankan      html  css  js  c++  java
  • 汇编语言程序——十六进制输出程序中标识符的内存地址

    PS:不更实验了。。一来局限性比较大,二来感觉把自己也捐进去了。。从这个实验开始我都忘了要扩展了。。

    前排转载一个个人感觉关于org 100h讲解比较详细的博客:https://blog.csdn.net/ruyanhai/article/details/7177904

    首先知道内存地址为[段地址:偏移量],而这里打算输出的标识符num1在数据段里,我们可以通过mov ax,num1得到它的偏移量。

    因为不能直接显示整个十六进制数,我们通过移位截取地址中的每一位十六进制数,然后转换成ASCII码来逐位输出,具体看代码。如有错误请指正。

    ;内存地址为[段地址:偏移量],这里输出标识符num1的内存地址
    org 100h
    
    start:
       mov ax,cs
       mov ds,ax
       mov ss,ax
       mov ax,0B800h
       mov es,ax
    
    print_address1:      ;通过移位得到段地址的每一位十六进制数,然后放到相应位置                 
       dec word[i]
       mov ax,word[i]
       cmp ax,-1         ;判断循环是否执行4次(输出4位十六进制数),是则退出循环
       jz mid
       mov ax,word[i]
       mov bx,4
       mul bx
       mov cx,ax         ;计算要移位的位数,为4*i,然后保存在cx里
       mov ax,ds         ;ax=ds
       shr ax,cl         ;将ds右移cl位(cl依次为12,8,4,0)
       and al,0fh        ;得到要取的某一位十六进制数
       or  al,30h        ;转换成ASCII码
       cmp al,58         ;判断是否小于58,小于说明是数字,否则是字母,还要加上7得到正确的ASCII码
       jl  digit1      
       add al,07h
    digit1:
       mov ah,0x07       ;设置字符属性
       mov cx,ax         ;把字符存在cx
       mov ax,3          
       sub ax,word[i]
       mov ax,ax
       mov bx,2
       mul bx
       mov bp,ax         ;计算地址,为[es:(3-i)*2]
       mov [es:bp],cx
       jmp print_address1
    
    mid:
       mov [es:8],byte ':'
       mov [es:9],byte 0x07
       mov word[i],4
    
    print_address2:       ;通过移位得到偏移量的每一位十六进制数,然后放到相应位置 
       dec word[i]
       mov ax,word[i]
       cmp ax,-1          ;判断循环是否执行4次(输出4位十六进制数),是则退出循环
       jz end
       mov ax,word[i]
       mov bx,4
       mul bx
       mov cx,ax          ;计算要移位的位数,为4*i,然后保存在cx里
       mov ax,num1        ;ax=num1的地址偏移量
       shr ax,cl          ;将ds右移cl位(cl依次为12,8,4,0)
       and al,0fh         ;得到要取的某一位十六进制数
       or  al,30h         ;转换成ASCII码
       cmp al,58
       jl  digit2         ;判断是否小于58,小于说明是数字,否则是字母,还要加上7得到正确的ASCII码
       add al,07h
    digit2:
       mov ah,0x07        ;设置字符属性
       mov cx,ax          ;把字符存在cx
       mov ax,3
       sub ax,word[i]
       mov ax,ax
       mov bx,2
       mul bx
       mov bp,ax
       add bp,10          ;计算地址,为[es:(3-i)*2+10]
       mov [es:bp],cx
       jmp print_address2
    
    end:
       mov [es:18],byte 'H'
       mov [es:19],byte 0x07
       jmp $
    
    datadef:
       num1 dw 1234h
       i    dw 4
       num2 dw 075Ah

    得到的地址如下:(注意改代码会导致输出不同,因为每条指令的机器码大小可能不一样)

    现在怎么证明输出的内存地址是正确的呢?我们开gdb模式看一下:

    可以看到,num1为1234h,此时存储在075A:01AB的位置,对比输出知道偏移量是没问题的,但为什么段地址不对呢?改了很久未果,询问老师得到回复说在DosBox中debug与实际运行的段值是不一样的。当我进一步询问怎么得到运行段值时,他说以后再说。(???)

    无奈到此作罢。以后可能再进行修改。

    终究独木难支。
  • 相关阅读:
    WPF线程中获取控件的值和给控件赋值
    sublime text3 安装以及主要插件安装
    云服务IaaS,PaaS,SaaS
    What is JSON
    Core Java
    英语单词及语义
    设置PyCharm创建文件时自动添加头文件
    【练习】字典的循环遍历:实现多层级节点存取
    字符串格式化
    常用数据类型的方法--str、int、list、dict
  • 原文地址:https://www.cnblogs.com/yanying7/p/14529029.html
Copyright © 2011-2022 走看看