汇编语言程序——十六进制输出程序中标识符的内存地址

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与实际运行的段值是不一样的。当我进一步询问怎么得到运行段值时,他说以后再说。(???)

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

终究独木难支。
原文地址:https://www.cnblogs.com/yanying7/p/14529029.html