十六、数据处理问题的若干补充

1. 内存单元作为第一个操作数或唯一的操作数时的情形:

    1) 前面讲过当内存访问作为第一个操作数时不能使用之前说过的法则,即使第二个操作数是寄存器也不行;

    2) 这个时候就需要显式指明内存单元的类型了,可以使用byte ptr或word ptr操作符来指明内存单元是字节型的还是字型的;

!注意:这两个操作符是编译器提供的操作符,并不是汇编指令,不能直接一步翻译成二进制码;

    3) 使用的情形:

         i. 首先是第一个操作数必须是内存单元;

         ii. 第二个操作数可以是寄存器或立即数,不能两个操作数都是内存单元,否则会报错的!

         iii. 如果指令是单操作数时也行;

!注意:即使第一个操作数是寄存器而第二个是内存也可以使用,但是不建议这样做,因为这种情况是可以自动推断的,不要多此一举;

    4) 示例:

assume cs:code

code segment
	mov		byte ptr [bx], 12
	add		word ptr [3FH + bp], cx
	sub		byte ptr [bp][si][9H], cl
	and		word ptr 0FCH[bx], 1001B
	or		byte ptr [bp + 9], bh
	inc		word ptr [bx]

	mov		ax, 4C00H
	int		21H
code ends

end
!注意:还是不能将[立即数]作为第一个操作数,编译器会将其理解成一个立即数看待的!


4. 除法指令div:

    1) 可以把div看做是mul的逆运算,因此div也有两种类型,分别对应着mul的两种类型;

    2) 对应于字节型的mul,div的运行方式是,将被除数放在ax(mul的结果),除数放在8位寄存器或内存中,商默认存放在al中(mul的第一个默认乘数),而余数放在ah中;

    3) 对应于字型的mul,被除数的低位放在ax中高位放在dx中(mul的结果),除数放在16位寄存器或内存中,商默认放在ax中(mul的第一个默认乘数),而余数放在dx中;

    4) div使用方法,先对数据范围进行估计,然后执行上述步骤(即准备被除数和除数),最后直接执行"div 除数"指令即可,结果就保存在相应的寄存器中了;

    5) 实例:1001 / 100和100001 / 100:

assume cs:code

code segment
	mov		ax, 1001
	mov		bl, 100
	div		bl

	mov		ax, 86A1H
	mov		dx, 1H
	mov		bx, 100
	div		bx

	mov		ax, 4C00H
	int		21H
code ends

end
运行结果:

*1. 商是0AH,余数是1H

*2. 商是3E8H,余数是1H

5.   定义双字型数据的伪指令——dd:

       a. 即define double word,可以定义双字型数据(32位);

       b. 程序示例——将第一个数除以第二个数的商放在第三个数中:

assume cs:code, ds:data

data segment

	dd 100001
	dw 100
	dw 100

data ends

code segment

	start:

		mov ax, data
		mov ds, ax

		mov ax, ds:[0]
		mov dx, ds:[2]
		div word ptr ds:[4]
		mov ds:[6], ax

	mov ax, 4c00h
	int 21h

code ends

end start

6.   重复定义数据的伪指令——dup:

       a. 使用规则:db/dw/dd 重复次数 dup (数值列表)

       b. 即将数值列表中的数值重复定义n次,比如:

            db 3 dup (1, 2, 3)

            即将字节型数值1, 2, 3重复定义3次,即定义了1, 2, 3, 1, 2, 3, 1, 2, 3这9个字节数据


7.   一个较长的程序:

       i.   将年份、收入、雇员数、平均收入填入table表中;

       ii.  程序如下:

assume cs:code, ds:data

data segment

	db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
    db '1993','1994','1995'
    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11452,14430,15257,17800

data ends

table segment

	db 21 dup ('year summ ne ?? ')

table ends

code segment

	start:

		mov ax, data
		mov ds, ax

		mov ax, table
		mov ss, ax

		mov bx, 0
		mov si, 168
		mov bp, 0

		mov cx, 21
	s:
		
		;done year
		mov ax, [bx + 0]
		mov	[bp + 0], ax
		mov ax, [bx + 2]
		mov [bp + 2], ax

		;done n
		mov ax, [si]
		mov [bp + 10], ax

		;done sum
		mov ax, [bx + 84]
		mov [bp + 5], ax
		mov dx, [bx + 86]
		mov [bp + 7], dx

		;done avg
		div word ptr [bp + 10]
		mov [bp + 13], ax

		add bx, 4
		add si, 2
		add bp, 10h

		loop s

	mov ax, 4c00h
	int 21h

code ends

end start

              iii. 程序运行结果如下:

                   十六、数据处理问题的若干补充_第1张图片


你可能感兴趣的:(汇编与接口,汇编语言)