The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: zekyr on July 30, 2011, 06:29:10 PM

Title: Older Registers and Print macro
Post by: zekyr on July 30, 2011, 06:29:10 PM
Hello! I'm new to the forum; I've got just a little bit of experience with hcs12 asm but I'm completely new to all this and was hoping for a little help! I also wanted to get my first post out of the way

I installed the MASM32 sdk and fired up Qeditor and am having a bit of trouble understanding why this will compile and run correctly

test proc
    mov ebx, 10
FARK:   
    print str$(ebx),10,13
    dec ebx
    jnz FARK
    ret
test endp

but when i change the registers to say

test proc
    mov bl, 10
FARK:   
    print str$(bl),10,13
    dec bl
    jnz FARK
    ret
test endp

it will compile run and hang

I thought BL was a byte wide; and im wondering where i went wrong with this.
Title: Re: Older Registers and Print macro
Post by: MichaelW on July 30, 2011, 08:27:08 PM
The problem is that the str$ macro, like other similar macros, is coded to take a DWORD parameter.

; ----------------------------------------------------------
  ; function position macros that takes a DWORD parameter and
  ; returns the address of the buffer that holds the result.
  ; The return format is for use within the INVOKE syntax.
  ; ----------------------------------------------------------
    str$ MACRO DDvalue
      LOCAL rvstring
      .data
        rvstring db 20 dup (0)
        align 4
      .code
      invoke dwtoa,DDvalue,ADDR rvstring
      EXITM <ADDR rvstring>
    ENDM


You can correct the problem by extending BL to 32 bits:

tester proc
    mov bl, 10
FARK:
    movzx eax, bl
    print str$(eax),10,13
    dec bl
    jnz FARK
    ret
tester endp


I changed your procedure name because TEST is the name of an instruction.


Title: Re: Older Registers and Print macro
Post by: dedndave on July 30, 2011, 08:34:32 PM
best to use EBX anyways
DEC BL is 2 bytes
DEC EBX is 1 byte   :P

i am surprised it assembled with the proc named "test", though   :bg
Title: Re: Older Registers and Print macro
Post by: zekyr on July 30, 2011, 08:39:17 PM
That makes sense!


also it didn't assemble, I gave the procedure a dumb name so I changed it really quickly to test when I posted the code then realized it doesnt assemble with that name =D . Thanks a lot though! By 2 bytes on DEC BL do you mean that instruction assembles into 2 bytes?
Title: Re: Older Registers and Print macro
Post by: dedndave on July 30, 2011, 08:41:27 PM
pretty sure
INC and DEC on a full-size general register are special single-byte opcodes
nice to know, but burned up a lot of opcode space, if you ask me
Title: Re: Older Registers and Print macro
Post by: MichaelW on July 30, 2011, 09:10:54 PM
In greater detail, the problem is that ML 6.14 has a bug that causes it to generate this code:

00000002  68 00000000 R  push   OFFSET ??0019
00000007  6A 00          push   000h
00000009  8A C3          mov    al, bl
0000000B  66| 0F B6 C0   movzx  ax, al
0000000F  66| 50         push   ax
00000011  E8 00000000 E  call   dwtoa


Which is pushing a DWORD followed by a WORD, 6 bytes total. In 32-bit code the stack must be maintained at a minimum 4-byte alignment, and the generated code is failing to do this. If the generated code were like this:

00000002  68 00000000 R  push   OFFSET ??0019
00000007  66| 68 0000    push   WORD PTR 0
0000000B  8A C3          mov    al, bl
0000000D  66| 0F B6 C0   movzx  ax, al
00000011  66| 50         push   ax
00000013  E8 00000000 E  call   dwtoa


Then there would be no problem.


Title: Re: Older Registers and Print macro
Post by: dedndave on July 31, 2011, 12:22:35 AM
huh ?
are you talking about the str$ macro ?
Title: Re: Older Registers and Print macro
Post by: MichaelW on July 31, 2011, 12:55:44 AM
Yes, the disassembly is the generated code for the str$ macro when its arg is BL. Sorry, I should have provided more context.
Title: Re: Older Registers and Print macro
Post by: dedndave on July 31, 2011, 12:59:47 AM
i guess you could dress up those macros to handle byte and word registers
but, i never really need them that way
once in a while, i might do somthing like this...
        print   right$(uhex$(eax),2),32
:bg
Title: Re: Older Registers and Print macro
Post by: MichaelW on July 31, 2011, 01:03:18 AM
Or recode the macro to check the size and handle it accordingly, but I doubt that it's worth the effort. Newer versions of ML may not have this problem - I can't recall testing beyond 6.15.