   Some help with x86 asm, the mul instruction
  Basically, what I am trying to do is write a macro to put characters to the screen without using an interrupt.  What I have so far:%macro FastChar 4 ;vidaddress, char, x, ymov DI, [%1]  ;move address of the video buffer to DImov ax, 50h  ;move the width of line to ax for mulmul byte [%4];mul the line width by y, trouble here somewhereadd di,ax  ;add to vid addressadd di, [%3] ;add x to everythingshl di,1;mult by 2 to skip attribute bytexor ax, axmov AX, %2 stosw%endmacroThe problem is simple.  If I put in x as 5 and y as 0, everything works great. But If I change the value of Y, the character appears at some random part of the screen.  If I change it to this:%macro FastChar 4 ;vidaddress, char, x, ymov DI, [%1]  ;move address of the video buffer to DI;mov ax, 50h  ;move the width of line to ax for mul NOT DONE NOW;mul byte [%4];mul the line width by y NOT DONE NOWadd di,50h  ;add the amount of a single line to vid address CHANGE HEREadd di, [%3] ;add x to everythingshl di,1;mult by 2 to skip attribute bytexor ax, axmov AX, %2 stosw%endmacroIt works as it should, the character appears at x,1.  So obviously, my fault comes in at the mul instruction.  Can anyone point me in the direction of what I'm doing wrong?  (If it matters, I'm using NASM under DOS)   
Quote:Original post by Craig Mmov DI, [%1]  ;move address of the video buffer to DI[...]shl di,1;mult by 2 to skip attribute byteAre you sure you want to multiply the address of the video buffer (plus some offset) by two? Wouldn't it make more sense to multiply just the offset by two and then add the address of the video buffer?Not sure if this is related to your problem, though.;  You know, that may be part of the problem, but I still think theres something going on with Mul, as this doesn't work either:%macro FastChar 4 ;vidaddress, char, x, ymov DI, [%1]mov ax, 50h  ;width of line, trouble!mul byte [%4]; times y, trouble here somewhereadd ax, [%3] ;add xshl ax,1;mult by 2, to skip attrib add di, axxor ax, axmov AX, %2 stosw%endmacroThanks for your advice, fred. Anyone else have any suggestions?   ;  I have solved it for youI was sitting at home watching the news and I thought about your shl ax,1 instruction and when I checked just now I confirmed my suspicionsYou almost had it. I looked at what your multiplying y against and it was 80 which is half right. You missed the attribute byte so you would multiply y by 160.Your x offset I had to fix a little because you were actually multiplying doing (w*y+x)*2 (w is your value of 80)When you should be doing(w*y)+(x*2) (w is the value 160 because 1 char is 2 bytes)%macro FastChar 4 ;vidaddress, char, x, ymov ax, A0h; This accounts for the attribute byte aswell.mul [%4]   ; This is  correctmov di, [%3]shl di, 1  ; This or add di, di (Not sure which is faster)add di, ax ; I also integrated the vidaddress and offset hereadd di, [%1]mov ax. [%2]stosw%endmacroGive this ago.   