Jump to content
  • Advertisement
Sign in to follow this  

coding fun with MASM

This topic is 4236 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hey I picked up a book on assembly code with masm and am trying to get the knack of this stuff.... i just want to output a binary digit. i can figure out how to do it with a hex number, but the binary's got me all sorts of confused. here i my code for the hex output
	.MODEL	small
	.STACK	100h
cr	EQU	0Dh
lf	EQU	0Ah

digit_table	DB	'0123456789ABCDEF'
hex_str	DB	'0000h', cr, lf, '$'
divisor	DW	16

number	DW	0F8D2h


	; copy the number to AX so it doesn't get clobbered.
	; As we loop AX will contain the high bits yet to be converted to hex   
        ; digits.
	mov	ax,	number			
	; I'm using DI to index the converted hex string as an array
	; starting with index 3 (the 4th hex char) and working my   
	; way back to index 0 (the 1st hex char).  I have to use DI because
	; memory indexing (like the "mov [di], al" instruction) requires
	; an index register as the first operand
	mov	di,	OFFSET hex_str	; Get the memory address of the hex 
                                        ; string I am filling.
	add	di,	3		; Add 3 to shift the address by 3 bytes.

	mov	cx,	4		; Do the following loop 4 times... CX 
                                        ; is like the "i" of

	; while (cx != 0)								;---------------------------------------------------
	cmp	cx,	0			; Compare CX to zero.
	je	end_hex_loop			; JUMP to the "end_hex_loop" 	
	; Division requires a 32-bit dividend and a 16 bit divisor.  Since our 
        ; registers are only 16 bits, the "div" instruction fakes a 32 bit 
        ; number by assuming the dividend's high 16 bits are in DX and low 16 
        ; bits in AX.  The number we're working on is already in AX and is only
	; 16 bits, but since the instruction requires 32 bits we zero out DX so 
        ; the value of the number isn't affected.  After the division 
        ; instruction completes the quotient is in AX and the remainder in DX.  
        ; Dividing our number by 16 gives a remainder that is the lowest order
	; nibble we're tunring to a hex digit and a quotient that represents 
        ; the rest of the number left to convert.
	mov	dx,	0	; Zero out the high 16 bits of the DX:AX 
	div	divisor		; Divide (unsigned) the number by 16
	push	ax		; The "xlat" instruction below requires the use 
                                ; of AL so we must save our quotient
	mov	bx,	OFFSET digit_table	; Get the address of 
                                                ; the "digit_table".  "xlat" 
                                                ; expects this address in BX.
	mov 	al,	dl		        ; AL needs to indicate 
                                                ; to "xlat" which position of 
                                                ; the array to index.
	xlat					; Grab the hex digit indexed by 
                                                ; BX[AL] and store it in AL
	mov	[di],	al			; Store the hex digit in 
                                                ; the "di"th position of our 
						; output string
	pop	ax				; Get our quotient back from 
                                                ; the stack

	sub	di,	1			; "di--" shifts our string 
                                                ; index BACK a byte to prepare
						; for the next loop iteration
	sub	cx,	1			; Decrement our loop index

	jmp	hex_loop			; Jump back to the top of 
                                                ; our "while" loop.

	; Print our hex string to the screen using the PROCEDURE
	; we developed in class
	mov 	ax,	OFFSET hex_str		
	call	disp_str

; disp_str : Display string of bytes using 
;            DOS int 21h, function 09h
; INPUT : AX should contain the address of 
;         the string of bytes
disp_str	PROC
	push	ax
	push	dx

	mov	dx,	ax
	mov	ah,	09h
	int	21h

	pop	dx
	pop	ax
disp_str	ENDP

i think its easier to work with hex numbers than with binary...

Share this post

Link to post
Share on other sites
It's far easier to work with binary than with hex. The processor works using a binary logic, so you just need to use the simple way.

The basic instructions you need are:
* shl (left shift by one bit)
* jc (jump if carry)
If you want to avoid any jumps, you can use adc:

mov eax, my_number ; your number is in eax
mov ecx, 32 ; loop count is in ecx

xor ebx, ebx ; set ebx to 0
shl eax, 1 ; left shift eax by one
; if the MSB is 1, the carry
; flag will be set
adc ebx, 0 ; ebx = ebx + 0 + carry flag

; Now ebx contains either 1 or 0, depending on the MSB of eax
; you can print it using a print routine
; note that if you replace the constant with the value of the '0' char,
; you directly get the character you'll want to display

loop the_loop ; ecx--, then loop to "the_loop" only if ecx != 0

That's all.

Of course, this routine is very specialized - it also don't take the output to a string into account (but this can be solved rather easily).

As you see, it is far easier than the hex version [smile]


Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!