在16位的处理器上,做加法的指令是add,但是他每次只能做8位或者16位的加法,除此之外,还有一个带进位的加法指令adc(Add With Carry),他的指令格式和add一样,目的操作数可以是8位或者16位的通用寄存器或者内存单元,源操作数可以是与目的操作数宽度一致的通用寄存器,内存单元或和立即数(但目的操作数和源操作数同为内存单元除外)。不过,ac指令在执行的时候,除了将目的操作数和源操作数想加,还要加上当前的标志寄存器的CF位。
adc指令对OF,SF,ZF,CF和PF的影响视计算结果而定。
课后习题要求我们编写一段主引导扇区的程序,计算1-1000的累加和,1-1000的累加和是500500,超过了16位,需要两个两个寄存器来储存,而且储存过后要显示数位,那就要用到32位的除法(一开始我把两个位拆开来了,结果老是不对还不知道怎么回事,后来才发现寄存器的加法是16位才会溢出,而不是我们十进制溢出,所以这样做是错的)
div这个指令计算32位除法要保证被除数的高16位在dx上,低16位在ax上,结果的商在ax,余数在dx,也就是说商必须是16位的才行,而我们知道500500/10是50050<65535,结果就对了。
jmp near start ;计算1+2+3+...1000的大小 message db '1+2+3+...+1000=' start: mov ax,0x7c0 mov ds,ax mov ax,0xb800 mov es,ax mov si,message mov di,0 mov cx,start-message cld @g: movsb mov byte[es:di],0x07 inc di loop @g xor ax,ax xor dx,dx mov cx,1000 @f: add ax,cx adc dx,0x0000 loop @f ;设定ss和sp的位置 xor cx,cx mov ss,cx mov sp,cx xor cx,cx mov bx,10 ;拆解答案 @a: inc cx div bx or dl,0x30 push dx xor dx,dx cmp ax,0x0000 jne @a ;以下显示各个数位 @b: pop dx mov [es:di],dl inc di mov byte[es:di],0x07 inc di loop @b jmp near $ times 510-($-$$) db 0 dw 0xAA55
博客园居然支持汇编代码,好评。