buffer: times 64 db 0
And I know I can create a buffer on the stack like this:
sub esp, 64
mov ebx, esp ;save the start point of the buffer
But how do I zero out the buffer on the stack? In C, I would just do
something like:
char buffer[64] = {0};
What's the equivalent in assembly using NASM?
Thanks,
Brian
I am unfamiliar with NASM and I think it also depends on the object
format you are using, but even if you put a zero as in above, doesn't
the bss section still need to be zero'd? The above line will only
occupy 64 bytes, it won't set it to zero. Am I correct?
> And I know I can create a buffer on the stack like this:
>
> sub esp, 64
> mov ebx, esp ;save the start point of the buffer
>
> But how do I zero out the buffer on the stack? In C, I would just do
> something like:
>
> char buffer[64] = {0};
Use your favorite C Compiler and compile this. Then either tell
the compiler to output Assembly code, or disassemble it yourself
and see what the compiler did.
> What's the equivalent in assembly using NASM?
There are many ways. (I don't use NASM, but you should
be able to convert it easy enough)
1.
mov ecx,((64+3)>>2)
xor eax,eax
@@: push eax
dec ecx
jnz short @b
2.
sub esp,((64+3) & ~3)
xor eax,eax
...
mov [esp+n],eax
mov [esp+n+4],eax
mov [esp+n+8],eax
...
3.
sub esp,((64+3) & ~3)
mov ecx,((64+3)>>2)
xor eax,eax
mov ebp,esp
@@: mov [ebp+n],eax
add ebp,4
dec ecx
jnz short @b
4.
sub esp,((64+3) & ~3)
mov ebx,esp
push byte 64
push byte 0
push ebx
call memset ; assuming your DS == SS
5.
your favorite code goes here
Ben
--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Forever Young Software
http://www.frontiernet.net/~fys/index.htm
To reply by email, please remove the zzzzzz's
Batteries not included, some assembly required.
>I'm trying to better understand data structures in assembly. I know I
>can create a zero filled buffer in the bss section in NASM with this:
The bss section is by definition not initialized by the program, so
you have to clear it yourself.
>buffer: times 64 db 0
This should get an error in the bss section.
>And I know I can create a buffer on the stack like this:
>
>sub esp, 64
>mov ebx, esp ;save the start point of the buffer
>
>But how do I zero out the buffer on the stack? In C, I would just do
>something like:
>
>char buffer[64] = {0};
Which does what I show below.
>What's the equivalent in assembly using NASM?
This will work for either the stack, or bss: (baring typos)
xor al,al
mov ecx,64
lea edi,buffer ; may need [] ?
rep stosb
OR:
xor eax,eax
mov ecx,16
lea edi,buffer ; may need [] ?
rep stosd
--
ArarghMail807 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html
To reply by email, remove the extra stuff from the reply address.
>On Fri, 18 Jul 2008 19:34:08 -0700 (PDT), "bwa...@yahoo.com"
><spam...@crayne.org> wrote:
>
>>I'm trying to better understand data structures in assembly. I know I
>>can create a zero filled buffer in the bss section in NASM with this:
>
>The bss section is by definition not initialized by the program, so
>you have to clear it yourself.
Not familiar with NASM or its linker, but with MASM32 and the standard
PE linker the BSS section (called .data? in MASM) is automatically
zeroed. In this section you can not specify a fill value, you must
use ? or MASM reports an error, but when the app runs that section is
always filled with zeros.
Best regards,
Bob Masta
DAQARTA v4.00
Data AcQuisition And Real-Time Analysis
www.daqarta.com
Scope, Spectrum, Spectrogram, Sound Level Meter
FREE Signal Generator
Science with your sound card!
Hi Brian,
Well... In -f obj (OMF) output format, Nasm will tolerate this - since
it doesn't know what ".bss" means. In (all?) other formats, this will
generate a warning (64 of 'em, actually) "attempt to initialize memory
in a nobits section: ignored". In an uninitialized (.bss) section,
there's "nothing there", so it would be "conceptually impossible" for
Nasm to zero it. That would be the right way to do it in an initialized
(.data) section.
In executable formats *other* than dos .com files, the loader - not Nasm
- zeros the .bss section. Some "standard"... the "Intel ABI" I think,
requires it... I think... I'm not sure whether we're "supposed to" count
on this or not. Seems to me like an "error" to ASSume anything about
memory that we haven't explicitly initialized.
In a dos .com file, the .bss section is truly uninitialized - whatever
"garbage" was there, stays there. We can demonstrate this:
org 100h
section .bss
answer resb 1
section .text
cmp byte [answer], 42
jz printyes
mov al, 'N'
int 29h
jmp common
printyes:
mov al, 'Y'
int 29h
common:
mov byte [answer], 42
ret
First time you run this, it (probably) will print 'N'. run it again -
without doing anything to mess with memory - and it'll print 'Y'.
(untested, but that's the way I remember it)
I'm a little unclear what Nasm does with "resb" (and friends) in -f obj
output format. It *seems* that if your uninitialized data is collected
at the end of your source, it does not become part of the on-disk file.
If initialized data follows it, Nasm silently zero-fills it, and it
*does* add to the file size. It may depend on the linker, as well.
[if anyone knows/remembers details of the OMF format, the
nasm-development team is looking for "verification" of a proposed patch]
> And I know I can create a buffer on the stack like this:
>
> sub esp, 64
> mov ebx, esp ;save the start point of the buffer
>
> But how do I zero out the buffer on the stack? In C, I would just do
> something like:
>
> char buffer[64] = {0};
>
> What's the equivalent in assembly using NASM?
Call memset? That's the way C does it...
I'd probably do, depending on mood...
BUFSIZ equ 64 ; damn well *better* be a multiple of 4!!!
...
sub esp, BUFSIZ
mov ebx, esp ; you said to...
mov ecx, BUFSIZ - 4
xor eax, eax
.my_memset:
mov [esp + ecx], eax
sub ecx, byte 4
jns .my_memset
...
I'm not saying that's a "good" way to do it - or even right (untested...
I should know better...), but I'd probably do something like that...
Possibly something involving "rep stosd"...
How would gcc handle it? Depends on version - and switches - I'm sure.
Here's *one* way gcc does it:
(suppose I'd better post the source... this is just "junk" that I added
the "={0}" to...)
#include <stdio.h>
#include <unistd.h>
int main()
{
char name[80] = {0};
int name_len;
printf ("Please tell me your name? ");
/* fflush(stdout); */
name_len = read (0, name, 79);
name[name_len - 1] = 0;
/* gets (name); */ /* this *does* flush stdout! */
/* we know better than to use gets(), right? */
printf ("Hello, %s! Welcome to Linux Assembly!\n", name);
return 0;
}
Here's what "objdump -d" thinks of "main":
080483d0 <main>:
80483d0: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483d4: 83 e4 f0 and $0xfffffff0,%esp
80483d7: ff 71 fc pushl -0x4(%ecx)
Hmmm... Align the stack and "re-push" the return address?
80483da: 55 push %ebp
80483db: 89 e5 mov %esp,%ebp
80483dd: 83 ec 68 sub $0x68,%esp
Note that this is more than the 0x50 bytes in our buffer.
80483e0: 89 5d fc mov %ebx,-0x4(%ebp)
Save caller's reg? Instead of "push ebx"?
80483e3: 8d 5d a8 lea -0x58(%ebp),%ebx
Address of our buffer?
80483e6: 89 4d f8 mov %ecx,-0x8(%ebp)
Lemme see... ecx was initial esp + 4... address of "argc"??? WTF???
80483e9: 89 1c 24 mov %ebx,(%esp)
80483ec: c7 44 24 08 50 00 00 movl $0x50,0x8(%esp)
80483f3: 00
80483f4: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp)
80483fb: 00
Here, I believe we're "pushing without push" the parameters for memset
onto the stack.
80483fc: e8 c7 fe ff ff call 80482c8 <memset@plt>
... and that's how we zero the buffer...
8048401: c7 04 24 54 85 04 08 movl $0x8048554,(%esp)
8048408: e8 eb fe ff ff call 80482f8 <printf@plt>
"not-push" the (static) address of "please tell me..." and print it
804840d: 89 5c 24 04 mov %ebx,0x4(%esp)
8048411: c7 44 24 08 4f 00 00 movl $0x4f,0x8(%esp)
8048418: 00
8048419: c7 04 24 00 00 00 00 movl $0x0,(%esp)
8048420: e8 c3 fe ff ff call 80482e8 <read@plt>
"not-push" our buffer address (in ebx), length (-1), and "stdin", call
read...
8048425: c6 44 05 a7 00 movb $0x0,-0x59(%ebp,%eax,1)
Zero-terminate the string.
804842a: 89 5c 24 04 mov %ebx,0x4(%esp)
804842e: c7 04 24 70 85 04 08 movl $0x8048570,(%esp)
8048435: e8 be fe ff ff call 80482f8 <printf@plt>
"not-push" our buffer, format string, call printf...
804843a: 8b 4d f8 mov -0x8(%ebp),%ecx
Get that "address of argc" back into ecx...
804843d: 31 c0 xor %eax,%eax
"return 0".
804843f: 8b 5d fc mov -0x4(%ebp),%ebx
Restore caller's reg?
8048442: 89 ec mov %ebp,%esp
Get back our "aligned stack"...
8048444: 5d pop %ebp
Restore caller's reg.
8048445: 8d 61 fc lea -0x4(%ecx),%esp
Restore our "original stack".
8048448: c3 ret
Whew!
Why? 'Cause that's the way the compiler writer wanted it, I guess. Maybe
I should have looked at something with *just* that buffer in it...
Best,
Frank
>On Sat, 19 Jul 2008 02:18:33 -0500, ArarghMail807NOSPAM
><spam...@crayne.org> wrote:
>
>>On Fri, 18 Jul 2008 19:34:08 -0700 (PDT), "bwa...@yahoo.com"
>><spam...@crayne.org> wrote:
>>
>>>I'm trying to better understand data structures in assembly. I know I
>>>can create a zero filled buffer in the bss section in NASM with this:
>>
>>The bss section is by definition not initialized by the program, so
>>you have to clear it yourself.
>
>Not familiar with NASM or its linker, but with MASM32 and the standard
>PE linker the BSS section (called .data? in MASM) is automatically
>zeroed. In this section you can not specify a fill value, you must
>use ? or MASM reports an error, but when the app runs that section is
>always filled with zeros.
>
AFAIK, that (the clearing of bss) is a loader function, not the
assembler nor the linker. And, I don't remember there ever being a
guarantee that it will be cleared. Could be, but I don't remember
any. So, either I clear the whole bss, or just assume that it
contains garbage.
BTW, the clearing of bss being a loader function, the assembler or
linker or compiler used is not important. The rules are the same for
all.
<snip>
>[if anyone knows/remembers details of the OMF format, the
>nasm-development team is looking for "verification" of a proposed patch]
What's the question? I have OMF docs. Or search for SS0288.zip which
is the version that I have. It's a little old, though. :-)
Couldn't find a much more recent version, either. :-)
<snip>
>On Sat, 19 Jul 2008 02:18:33 -0500, ArarghMail807NOSPAM
><spam...@crayne.org> wrote:
>
>>On Fri, 18 Jul 2008 19:34:08 -0700 (PDT), "bwa...@yahoo.com"
>><spam...@crayne.org> wrote:
>>
>>>I'm trying to better understand data structures in assembly. I know I
>>>can create a zero filled buffer in the bss section in NASM with this:
>>
>>The bss section is by definition not initialized by the program, so
>>you have to clear it yourself.
>
>Not familiar with NASM or its linker, but with MASM32 and the standard
>PE linker the BSS section (called .data? in MASM) is automatically
>zeroed. In this section you can not specify a fill value, you must
>use ? or MASM reports an error, but when the app runs that section is
>always filled with zeros.
>
I did a little digging, and found that for DOS type programs written
in C, the bss is cleared by the C runtime startup code. For windows
programs written in C, there is no clearing routine in the startup
code, so windows must have zeroed it out. (Assumption, not necessarily
a good one!)
So for an assembler program, for DOS, you have to clear bss yourself,
for windows, you can try assuming that windows did it.
But I clear it out, anyway. It's only done once at the beginning of
the program, and that way I *KNOW* it has been zeroed out.
The is correct. A typo on my part; belongs to the data section.
I am assembling the file on windows since my only *nix box is 64 bit,
and I'm curious about 32 bit asm on windows. Where can I get more
information on the obj (OMF) format since that is what I am using
before using alink to link the file to a PE file? And how do I debug
the program in ollydbg if I don't break the program into sections?
I'm basically just creating a buffer to write strings for functions
like snprintf, so that I can write output to a messageboxa. My goal
is to understand both ways of creating a buffer, so that I have more
flexibility.
Thanks,
Brian
That works well. I just did this:
sub esp, 64
mov dword edi, esp ;store the location of the beginning of the buffer
in edi
xor eax, eax ; make sure al is zero for the call to stosb
mov dword ecx, 64 ; set counter to 64
rep stosb ; repeat stosb 64 times -- this could be done faster with
stosd 16?
Does stosb move up the stack by default or do I need to explicitly
specify the direction with cld?
Thanks,
Brian
<http://sourceforge.net/tracker/index.php?func=detail&aid=2010180&group_id=6208&atid=106208>
Sounds like Slavik knows what he's talking about. Just hoping for a
"second opinion"...
> I have OMF docs. Or search for SS0288.zip
Okay... this link seems to still work...
<http://www.powerbasic.com/files/pub/docs/SS0288.zip>
> which
> is the version that I have. It's a little old, though. :-)
Nothing wrong with *that*! :)
> Couldn't find a much more recent version, either. :-)
No 64-bit extensions, I guess. What a pity! :)
I'll try to find the ambition to RTFM on that. Should confirm that
that's what we want to do. Thanks for the tip, Arargh! Saved a lot of
searchin'...
Best,
Frank
Normally you would use COFF (-f win32) format to link a PE file, not
OMF, which is used by DOS, OS/2, and Win16, but not Win32/64.
-hpa
According the the NASM docs, there are some difference between the
output of the
COFF format and the win32 format, so NASM generates both.
I'm all for using a different format, but I need some help. Where do
I put my
import and extern library calls in my assembly when using win32 or
coff?
NASM is returning me errors. I did change the naming convention for
the segments,
and I did delete my ..start: entry point. But I'm not sure what to do
with those
library calls. For example:
import sprintf msvcrt.dll
extern sprintf
I get errors on the above.
That mostly depends on the processor in question.
>Does stosb move up the stack by default or do I need to explicitly
>specify the direction with cld?
stosb follows the direction bit.
In my programs, I generally clear it during initialization, and clear
it as soon as possible after setting it.
>ArarghMail807NOSPAM wrote:
>> On Sat, 19 Jul 2008 15:28:21 GMT, Frank Kotler <spam...@crayne.org>
>> wrote:
>>
>> <snip>
>>> [if anyone knows/remembers details of the OMF format, the
>>> nasm-development team is looking for "verification" of a proposed patch]
>>
>> What's the question?
>
><http://sourceforge.net/tracker/index.php?func=detail&aid=2010180&group_id=6208&atid=106208>
>
>Sounds like Slavik knows what he's talking about. Just hoping for a
>"second opinion"...
I would have to get the current version to check it out, but AFAIK,
all OMF records for 32-bit sections should be the OMF-32-bit version.
>> I have OMF docs. Or search for SS0288.zip
>
>Okay... this link seems to still work...
>
><http://www.powerbasic.com/files/pub/docs/SS0288.zip>
>
>> which
>> is the version that I have. It's a little old, though. :-)
>
>Nothing wrong with *that*! :)
>
>> Couldn't find a much more recent version, either. :-)
>
>No 64-bit extensions, I guess. What a pity! :)
No, never been done, AFAIK. Besides, the original record number
spacing should have been 4 to allow for that. And you would have to
write the 64-bit linker to use it. Better to stick to ELF or COFF.
>I'll try to find the ambition to RTFM on that. Should confirm that
>that's what we want to do. Thanks for the tip, Arargh! Saved a lot of
>searchin'...
For a slightly later version, search for "TIS1.1.pdf" Or, I can email
it if your t...@C--C---.N-- email address is still good.
...
>>> buffer: times 64 db 0
...
> The is correct. A typo on my part; belongs to the data section.
Okay...
> I am assembling the file on windows since my only *nix box is 64 bit,
> and I'm curious about 32 bit asm on windows.
You've got a 64-bit *nix box and you're screwin' around with OMF? Okay...
> Where can I get more
> information on the obj (OMF) format
That link Arargh gave:
<http://www.powerbasic.com/files/pub/docs/SS0288.zip>
will tell you more than you wanna know. (more than *I* wanna know,
anyway - that patch has been applied, so my question is moot) The Nasm
manual has a section...
<http://mysite.verizon.net/fbkotler/nasmdoc6.html#section-6.2>
> since that is what I am using
> before using alink to link the file to a PE file?
As hpa notes, "-f obj" is kind of an "obsolete" format for Windows.
MScoff would be the more "modern" way - Nasm's "-f coff" is for djgpp
coff, you'd want "-f win32" for Windows. The problem I had with "-f
win32" was knowing what to link against. The libraries with Hutch's
"MASM32" package worked, but that seemed like "cheating". I guess the
Nasm32 project has got libraries now.
http://www.asmcommunity.net/projects/nasmx/
What I liked about using "-f obj" and Alink is that, with an "import"
directive for every API you use, you don't need any library at all
(except for the .dlls themselves, of course!).
> And how do I debug
> the program in ollydbg if I don't break the program into sections?
I don't know what you mean by not breaking it into sections. If you
don't have a "segment"/"section" declared, Nasm will use a default
section - but it won't have the correct properties for a PE. I didn't
use Ollydbg much, but I found it complained about "entrypoint not in
code section" (or similar) if I didn't say "class=CODE" (dunno if it has
to be uppercase) in my section declaration:
section _TEXT use32 class=CODE
The name "_TEXT" is what the Borland tools liked, IIRC - shouldn't make
a difference to Alink(?). What issues are you running into with Ollydbg?
> I'm basically just creating a buffer to write strings for functions
> like snprintf, so that I can write output to a messageboxa.
Okay... Shouldn't need to have the buffer zeroed for that. Might help to
make *sure* your strings are zero-terminated. :)
> My goal
> is to understand both ways of creating a buffer, so that I have more
> flexibility.
Good plan. The "third way" would be to allocate memory on the fly.
Windows has got APIs for it - probably will zero the memory for you, if
you know how to ask - VirtualAlloc is the only one I know the name of...
Best,
Frank
>That link Arargh gave:
><http://www.powerbasic.com/files/pub/docs/SS0288.zip>
Acutally, you gave the link, I just memtioned what to search for.
<snip>
>Good plan. The "third way" would be to allocate memory on the fly.
>Windows has got APIs for it - probably will zero the memory for you, if
>you know how to ask - VirtualAlloc is the only one I know the name of...
More windows API 'Allocs' than you can shake a stick at (these don't
include any language based allocs, just WIN APIs):
VirtualAlloc
This function reserves or commits a region of pages in the virtual
address space of the calling process. Memory allocated by VirtualAlloc
is automatically initialized to zero.
VirtualFree, VirtualProtect, VirtualQuery
LocalAlloc
This function allocates the specified number of bytes from the heap
LocalFree, LocalReAlloc, LocalSize
HeapCreate
This function creates a heap object that is private to the calling
process. This reserves a contiguous block of the process's virtual
address space and allocates physical storage for a specified initial
portion of this block.
HeapAlloc, HeapDestroy, HeapFree, HeapReAlloc, HeapSize
GlobalAlloc
The GlobalAlloc function allocates the specified number of bytes from
the heap. Win32 memory management does not provide a separate local
heap and global heap.
GlobalDiscard, GlobalFree, GlobalLock, GlobalSize
Check a Win API reference for more details on any of these, or MSDN
online.
...
> For a slightly later version, search for "TIS1.1.pdf" Or, I can email
> it if your t...@C--C---.N-- email address is still good.
fbko...@verizon.net - the comcast address still works, too. No use
trying to hide - they've found me! :)
But don't bother, I found it:
<refspecs.freestandards.org/elf/TIS1.1.pdf>
ELF and OMF... weird! Again, thanks for the info!
Best,
Frank
>ArarghMail807NOSPAM wrote:
>
>...
>> For a slightly later version, search for "TIS1.1.pdf" Or, I can email
>> it if your t...@C--C---.N-- email address is still good.
>
>fbko...@verizon.net - the comcast address still works, too. No use
>trying to hide - they've found me! :)
That's why I change my email address every month, at least for news
purposes.
>But don't bother, I found it:
>
><refspecs.freestandards.org/elf/TIS1.1.pdf>
The copy I have is 721,248 bytes in size.
>ELF and OMF... weird! Again, thanks for the info!
The strange thing the I can't find any web site or presence for the
"TIS Committee" or any reference to its still existing. It's like
they got together in the early 90s, pumped out a few standards, and
disappeared.
After messing around with 64-bit assembly on *nix, I find that it's
better to just write C or use some
scripting language to cover most of the things I want to do. However,
I find writing C++ to be more
painful then writing assembly in windows. I just happen to be writing
on a 32 bit box. I also happen
to hate C++ and C#. Assembly is less painful in windows now that I
don't have to memorize a bunch
of interrupts.
> As hpa notes, "-f obj" is kind of an "obsolete" format for Windows.
> MScoff would be the more "modern" way - Nasm's "-f coff" is for djgpp
> coff, you'd want "-f win32" for Windows. The problem I had with "-f
> win32" was knowing what to link against. The libraries with Hutch's
> "MASM32" package worked, but that seemed like "cheating". I guess the
> Nasm32 project has got libraries now.
>
> http://www.asmcommunity.net/projects/nasmx/
>
> What I liked about using "-f obj" and Alink is that, with an "import"
> directive for every API you use, you don't need any library at all
> (except for the .dlls themselves, of course!).
importing the dll's directly in the code is less painful then having
to
create a lib file off of the dll's and linking it. I did fine one
lib
file all ready made at a win32 assembly site, but that file did not
include
msvcrt.dll. I'm going to look over the website you provided above.
Hopefully,
the above will show me how to make my own. Why wouldn't coff or
win32 provide
import functionality in addition to lib use? I understand how libs
can make
your life easier, but if I'm just pulling a few functions from a few
dlls, it
seems like over kill to have to link whole libraries. Would be nice
if NASM
extended win32 or coff with import functionality.
>
> > And how do I debug
> > the program in ollydbg if I don't break the program into sections?
>
> I don't know what you mean by not breaking it into sections. If you
> don't have a "segment"/"section" declared, Nasm will use a default
> section - but it won't have the correct properties for a PE. I didn't
> use Ollydbg much, but I found it complained about "entrypoint not in
> code section" (or similar) if I didn't say "class=CODE" (dunno if it has
> to be uppercase) in my section declaration:
>
> section _TEXT use32 class=CODE
That is how I have been writing my sections/segments in the past.
Looks like
win32 has rdata and info, which I am not really to sure as to their
use.
>
> > I'm basically just creating a buffer to write strings for functions
> > like snprintf, so that I can write output to a messageboxa.
>
> Okay... Shouldn't need to have the buffer zeroed for that. Might help to
> make *sure* your strings are zero-terminated. :)
That was why I wanted to zero them out. And I wanted to know how to
do it
without using another C function like memset or bzero.
>
> > My goal
> > is to understand both ways of creating a buffer, so that I have more
> > flexibility.
>
> Good plan. The "third way" would be to allocate memory on the fly.
> Windows has got APIs for it - probably will zero the memory for you, if
> you know how to ask - VirtualAlloc is the only one I know the name of...
Thanks. I'm still diggin' into the windows api. I understand the
*nix one
pretty well. I also need to get less dependent upon C function calls
in my assembly.
Thanks,
Brian
I have EasyDNS for my domain host and they forward my email based upon
the mappings I set up. They also provide a SMTP server so I can send
email from either location without having to change my email settings.
This also makes it easier for me to switch providers for receiving
email. I prefer Comcast since they support SSL email and it works
well using Outlook Express, Outlook, or Agent. I also use different
email addresses on my domain so I can give out private addresses that
I don't use in newsgroup posts or for registering with any stores.
if i have understood well on 32bit cpu
with "alink" there is a program called "alib"
:x> alib msvcrt.dll
should produce msvcrt.lib
that can be used for link functions in that msvcrt.dll with your program
with alink
something like
:x> alink your.obj msvcrt.lib