News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

moving a word to an array of bytes

Started by nickc86, May 09, 2017, 12:50:54 PM

Previous topic - Next topic

nickc86

I am trying to understand using operands of different sizes
Say I have the following:
array byte 8 dup (?)

But I want to access those 8 bytes in the following order:
byte byte byte alignbyte word word

Just as an example, maybe I want to do the following:
I want to store one char in the first three bytes, I want to store an unsigned word in the 5th and 6th byte and another unsigned word in the 7th and 8th byte.

Am I trying to do things that aren't possible?

LordAdef

No, it's pretty easy.

Get the address of array into a register
Iterate the register so it points to the place you want

For bytes you access via "Byte Ptr [reg]"
For words "word Ptr [reg]"

aw27

Quote from: nickc86 on May 09, 2017, 12:50:54 PM
I want to store one char in the first three bytes, I want to store an unsigned word in the 5th and 6th byte and another unsigned word in the 7th and 8th byte.
Am I trying to do things that aren't possible?

This is a way:


.386

.MODEL FLAT, STDCALL
option casemap:none

option dllimport:<msvcrt.dll>
printf PROTO C arg1:Ptr Byte, printlist: VARARG
option dllimport:<kernel32.dll>
ExitProcess   proto STDCALL :dword

Counter=1
Total=8

TmyStruct STRUCT
REPEAT Total
db Counter
Counter=Counter+1
endm
TmyStruct ENDS


.data
message db "byte1 %d byte2 %d byte3 %d word1 %d word2 %d",0

myStruct TmyStruct <>


.code

start proc
INVOKE printf, addr message, byte ptr myStruct[0], byte ptr myStruct[1], byte ptr myStruct[2],word ptr myStruct[4], word ptr myStruct[6]
invoke  ExitProcess, 0
ret
start endp


end start


; Output: byte1 1 byte2 2 byte3 3 word1 1541 word2 2055

nidud

#3
deleted

aw27

Quote from: nidud on May 09, 2017, 04:55:42 PM
Just some nit-picks regarding using the C-library functions in msvcer.dll.

These library functions have a startup and exit module, and the exit() function(s) makes a cleanup call to IO and stdio functions. This flushes streams and close any open open files. For this reason the exit() function should be instead of ExitProcess().


.386
.model flat, c
option casemap:none

option dllimport:<msvcrt.dll>
printf proto :ptr sbyte, :vararg
exit proto :dword


It does not apply in this case, when the process ends everything will be released, flushed and closed.
All libraries are notified that the process is closing and are given a chance to clean.
Check by yourself the DLLMain Entry Point.

nidud

#5
deleted

aw27

Quote from: nidud on May 09, 2017, 07:04:01 PM
Quote from: aw27 on May 09, 2017, 05:09:41 PM
It does not apply in this case

True, this is just nitpicking and it works fine for small test-snippets like this, so it's just a matter of (in my view good) habit.

The reason is that LIBC is the portable section of the code so the standard string/IO functions may also be in a local library, or a UNIX/Linux version and so on.

C libraries, whatever they are, are just part of the (sometime) hundreds of libraries linked to a program.
They simply are not entitled to any special treatment - even if statically linked.

nidud

#7
deleted

aw27

Quote from: nidud on May 09, 2017, 08:40:02 PM
and the DOS/OS2 versions will do different things to exit the program.

I am not concerned with Linux, DOS or OS2 :biggrin:
I don't think anyone really is, because I have seen everybody using ExitProcess all the time in here. I can also assure you that there is no danger at all when we use ExitProcess after any Standard C Library call.

nidud

#9
deleted

mineiro

From my tests, and I don't start by hello world program, I start from how to give control back to O.S. or exit function.
On ms-dos an exitprocess can be just 'ret'. On windows too, but on linux not, but this is a bad pratice.

int 20h to .com, int 21h to .exe, int 80h on linux 32, syscall on linux 64, ExitProcess on windows 32 and 64...
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

aw27

Quote from: nidud on May 09, 2017, 09:48:16 PM
Yes, me included. The reason I pointed this out in this case was that you included the library for printf, which also includes exit, and then added kernel32 for ExitProcess.

Actually, ExitProcess was not needed, Ret was enough and already there because the first thing I always do is put a Ret .  :lol: And when we use ExitProcess we don't need a Ret because it is never called.  :lol:

nickc86

So to store some data there it would be:

.data
myArray byte 8 dup (?)
.code
mov eax, OFFSET myArray
mov word ptr [eax + 6], 5645

And to retrieve:

mov cx, word ptr [eax + 6]

Is this correct?

jj2007

Quote from: mineiro on May 09, 2017, 10:22:27 PM
On ms-dos an exitprocess can be just 'ret'. On windows too

On Windows, ret will trigger RtlExitUserThread - not the best option. But it will indeed work most of the time.

See also Raymond Chen's If you return from the main thread, does the process exit?

nickc86

Also, the exit process stuff is pretty interesting. Although, I don't understand much of it right now. I am pretty new to masm, as I am sure you can tell  :icon_eek: