NASM - The Netwide Assembler

NASM Forum => Programming with NASM => Topic started by: ____florian on January 11, 2012, 11:36:26 AM

Title: problem with define
Post by: ____florian on January 11, 2012, 11:36:26 AM
I got a little problem with %define
have a code line:
Code: [Select]
sub esp, dword allVarsand allVars is defined like that:
Code: [Select]
%define kernelMZ 0x04
%define userMZ kernelMZ + 0x04
%define loadLibrary userMZ + 0x04
%define dwFileAttributes loadLibrary
;the find struct + 0x04
%define ftCreationTime dwFileAttributes + 0x08
%define ftLastAccessTime ftCreationTime + 0x08
%define ftLastWriteTime ftLastAccessTime + 0x08
%define nFileSizeHigh ftLastWriteTime + 0x04
%define nFileSizeLow nFileSizeHigh + 0x04
%define dwReserved0 nFileSizeLow + 0x04
%define dwReserved1 dwReserved1 + 0x04
%define cFileName dwReserved1 0x0348
%define cAlternateFileName cFileName + 0x38

%define allVars cAlternateFileName
%define file allVars
But if I want to assamble it I get this error:
Code: [Select]
error: comma, colon or end of line expectedIt would be nice if you know how to fix that :)
greetings florian
Title: Re: problem with define
Post by: Frank Kotler on January 11, 2012, 03:49:30 PM
Hi Florian,

What you've defined expands to:

Code: [Select]
sub esp, dword dwReserved1 + 0x04 0x0348 + 0x38

... which is not proper syntax, of course. Do you intend to have another '+' sign in there (which results in "dwReserved1" being undefined)... or what?

Code: [Select]
%define dwReserved1 dwReserved1 + 0x04

... looks a little "recursive" to me.

Are you trying to define a structure without using "struc"? Or what?


Title: Re: problem with define
Post by: ____florian on January 11, 2012, 09:05:55 PM
Hehe Ok I guess it is better to use a struct.
I dod not know/search for structs so I tryed to do it like that.
thank you for your help :)

Code: [Select]
struc vars
.kernelMZ resd 0x01
.userMZ resd 0x01
.loadLibrary resd 0x01
.dwFileAttributes resd 0x01
;the find struct + 0x04
.ftCreationTime resd 0x02
.ftLastAccessTime resd 0x02
.ftLastWriteTime resd 0x02
.nFileSizeHigh resd 0x01
.nFileSizeLow resd 0x01
.dwReserved0 resd 0x01
.dwReserved1 resd 0x01
.cFileName resb 0x0348
.cAlternateFileName resb 0x0e

.file resd 0x01
sub esp, vars
becomes: sub esp, 0
but I want to reserve size of the struct on the space...
is that possible?
can you help me again?

Title: Re: problem with define
Post by: ____florian on January 13, 2012, 08:07:39 PM
Title: Re: problem with define
Post by: Frank Kotler on January 13, 2012, 08:34:35 PM

Code: [Select]
sub esp, vars_size

See if that works...

I'm suspicious of "dwReserved0" (and 1) having that "dw" in the name, but you're reserving a dword. Might be "resw 0x01" there?


Title: Re: problem with define
Post by: ____florian on January 13, 2012, 09:18:50 PM
well... I thought dw means dword...
is there space for the struct reserved in the executable?
If yes: what do I have to do if I want just the size values.

Hope you understand what I mean. Sorry for the bad english :S
Title: Re: problem with define
Post by: Frank Kotler on January 13, 2012, 11:37:44 PM
Well... maybe "dw" does mean "dword" in this case. In Nasm syntax, we have "pseudo instructions"...

Code: [Select]
db 0 ; 8 bits
dw 0 ; 16 bits
dd 0 ; 32 bits
dq 0 ; 64 bits
dt 0 ; 80 bits (for FPU "extended precision")
do 0 ; 128 bits

These initialize (to zero) memory of the stated size. We can also reserve memory, uninitialized, to those sizes...

Code: [Select]
resb 11 ; 8 bytes - enough for an old 8.3 filename
resw 1 ; a single 16-bit "word"
resd 1 ; a 32-bit "dword"
; etc.

This can be confusing, because the word "word" can also be used to mean a "native machine size word" - was 16 bits, then 32 bits, now 64 bits (I guess). To Nasm, "word" means 16 bits, "dw" means "define word" or perhaps "data word". It looks like "dword" - I used to make that mistake a lot! "dd" is what we want for "define dword" or "data dword" (32 bits).

What you're doing looks like a "directory entry", but I'm not familiar with parts of it, and I don't know how many bits are supposed to be reserved for "dwReserve0". If this comes from a C "header" file - dirent.h or filesys.h or some such, feel free to post it. (I could probably find it...)

Nasm's "struc" (it's a built-in macro) does NOT reserve any space for the structure - it's like a "typedef". If you want to initialize a structure (fill in the values), you can use "istruc". To just reserve space for it, you could do something like...

Code: [Select]
section .bss
   my_struct resb vars_size

Or what you're doing...

Code: [Select]
sub esp, vars_size

That makes room for a "local variable" or "stack variable", sometimes called an "automatic variable" because it exists only for the duration of the function and is "freed" when the function exits.

I'm distracted - got company - let me get back to ya on this...


Title: Re: problem with define
Post by: Frank Kotler on January 15, 2012, 11:00:24 PM
Well... I just tried to "attach" this file. Mathi's right - it didn't work. So I'll just paste it in...

Code: [Select]
; get month in Linux... attempt to make it portable :)
; mixed asm and C :)

; nasm -f elf timec.asm
; gcc -o timec timec.o
; nasm -f win32 timec.asm --prefix _
; gcc -o timec.exe timec.o
; should be similar for your compiler

global main

extern gettimeofday
extern strftime
extern localtime_r
extern puts

; some structures for "time stuff"
; note that these are mere "typedefs" - no memory allocated

struc tv
    tv_sec resd 1
    tv_usec resd 1

struc tz
    tz_minuteswest resd 1
    tz_dsttime resd 1          ; obsolete! do not use!

struc tm
    tm_sec resd 1              ; Seconds. [0-60] (1 leap second)
    tm_min resd 1              ; Minutes. [0-59]
    tm_hour resd 1             ; Hours. [0-23]
    tm_mday resd 1             ; Day. [1-31]
    tm_mon resd 1              ; Month. [0-11]
    tm_year resd 1             ; Year - 1900.
    tm_wday resd 1             ; Day of week. [0-6]
    tm_yday resd 1             ; Days in year.[0-365]
    tm_isdst resd 1            ; DST. [-1/0/1]

%define OUTBUFSIZ 100h

section .bss

; reserve memory for our structures
    timeval resb tv_size
    timezone resb tz_size
    the_time resb tm_size
; etc...
    outbuf resb OUTBUFSIZ

section .data

; note that the "back apostrophes" allow us to use "\n" etc.
; a fairly "new" Nasm feature...
; as requested, the month.

;    the_format db `%B! :)\n`, 0

; or give strftime a bit more of a workout...

    the_format db `%A, %B %d, %G\n%l:%M %p - %D\n`, 0


section .text

; find out what time it is

    push timezone
    push timeval
    call gettimeofday
    add esp, 4 * 2
; make C do the difficult long division

    push the_time ; tm structure to fill
    push timeval  ; tv structure to work from
    call localtime_r
    add esp, 4 * 2

; and the tedious text lookup...
    push the_time   ; tm structure to work from
    push the_format ; format string in strftime syntax
    push OUTBUFSIZ  ; max
    push outbuf     ; buffer to fill
    call strftime
    add esp, 4 * 4
; we can print it without C's help...
; but we won't :)

    push outbuf
    call puts
    add esp, 4 * 1


This is not the best example - doesn't really "use" the internals of the structure... or their sizes... it's what I've got at hand that isn't specific to Linux... "supposed" to be portable... It may be some help(?). If not, we can discuss it more...