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.
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.
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
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?
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
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.
huh ?
are you talking about the str$ macro ?
Yes, the disassembly is the generated code for the str$ macro when its arg is BL. Sorry, I should have provided more context.
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
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.