Author Topic: Random Examples  (Read 35995 times)

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Random Examples
« on: February 08, 2010, 05:41:10 PM »
I know I've been saying for some time I was going to write a tutorial. However some personal/life stuff has gotten in the way and I don't really foresee me having any spare time to work on it. Sorry...

On a lighter, but related note, during my "drafting" of the tutorial I wrote an incremental set of examples which (although not optimised and no warrant of usability or usefulness here) were going to be the basis for the tutorial. Each chapter was going to introduce features of the macro engine as well as the common tasks which you might want to do as a Linux programmer. It starts out making heavy use of the Standard C Library and weens it's way off to the system-call interface. it also includes three XLib examples and a "Hello, World" daemon. I hope someone finds these useful. If you want to pick up where I left off and try to document these into a tutorial, you're more than welcome to them.

Regards,
Bryant Keller

http://assembly.ath.cx/files/examples.tar.gz

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Random Examples
« Reply #1 on: February 10, 2010, 02:17:15 AM »
Thanks, Bryant! Always looking for examples. Pity we're not going to see the tutorial!

I haven't had much time to look at 'em. By ex02 I'm confused, and by ex03, completely baffled!

Code: [Select]
; Filename: ex03.asm
; Developer: Bryant Keller
; Date: 05 Sep 2009
; Purpose: This program demonstrates
; procedural programming and
; the usage of environment
; variables.
; Build:
;  nasm -f elf -o ex03.o ex03.asm
;  gcc -o ex03 ex03.o

BITS 32

GLOBAL main
EXTERN puts
EXTERN exit

%define @ARG EBP + 8
%define @VAR EBP - 8

SECTION .data

strEnvironment DB '-----------------------', 10
DB ' Environment Variables', 10
DB '-----------------------', 0

strArguments DB '------------------------', 10
DB ' Command Line Arguments', 10
DB '------------------------', 0

SECTION .text

envs:
STRUC @ENVP
.envc RESD 1
.envp RESD 1
ENDSTRUC
STRUC $ENVP
.ptr RESD 1
ENDSTRUC
PUSH EBP
MOV EBP, ESP
SUB ESP, $ENVP_size

PUSH DWORD strEnvironment
CALL puts

MOV ESI, [@ARG + @ENVP.envp]
MOV ECX, [@ARG + @ENVP.envc]
DEC ECX
MOV EAX, 4
.scan_envs:
PUSH ECX
CMP ECX, 0
JE .done

DEC ECX

MOV EBX, [ESI + EAX]
OR EBX, EBX
JE .done

ADD EAX, 4
MOV [@VAR - $ENVP.ptr], EAX

PUSH EBX
CALL puts

MOV EAX, [@VAR - $ENVP.ptr]
POP ECX
JMP .scan_envs
.done:
XOR EAX, EAX
LEAVE
RET

args:
STRUC @ARGS
.argc RESD 1
.argv RESD 1
ENDSTRUC
STRUC $ARGS
.ptr RESD 1
ENDSTRUC
PUSH EBP
MOV EBP, ESP
SUB ESP, $ARGS_size

PUSH DWORD strArguments
CALL puts
ADD ESP, 4

MOV ESI, [@ARG + @ARGS.argv]
MOV ECX, [@ARG + @ARGS.argc]
DEC ECX
MOV EAX, 4
.scan_args:
PUSH ECX
CMP ECX, 0
JE .done

DEC ECX

MOV EBX, [ESI + EAX]
OR EBX, EBX
JE .done

ADD EAX, 4
MOV [@VAR - $ARGS.ptr], EAX

PUSH EBX
CALL puts
ADD ESP, 4

MOV EAX, [@VAR - $ARGS.ptr]
POP ECX
JMP .scan_args
.done:
XOR EAX, EAX
LEAVE
RET

main:
STRUC ENV
.argc RESD 1
.argv RESD 1
.envp RESD 1
ENDSTRUC
PUSH EBP
MOV EBP, ESP
PUSH DWORD [@ARG + ENV.argv]
PUSH DWORD [@ARG + ENV.argc]
CALL args

MOV ESI, [@ARG + ENV.envp]
MOV ECX, 4
XOR EAX, EAX
.continue:
MOV EBX, [ESI + ECX]

OR EBX, EBX
JE .count_done

ADD ECX, 4

INC EAX
JMP .continue
.count_done:
PUSH DWORD [@ARG + ENV.envp]
PUSH EAX
CALL envs

XOR EAX, EAX
PUSH EAX
CALL exit
LEAVE
RET

Sometimes you restore the stack after "puts", sometimes not. In particular, in your ".scan_envs:" loop...

         PUSH EBX
         CALL puts

         MOV EAX, [@VAR - $ENVP.ptr]
      POP ECX

ECX used to hold the count of environment variables, lovingly acquired in main. I don't think it does, anymore. It works anyway, because of the other "bailout"... which exits the loop with a register (or two! in this case) on the stack. LEAVE saves your asm, of course. I hope this "deferred cleanup" is explained in the tut, you do it a lot.

Then, in ex07...

Code: [Select]
%define PTR &

Aw, maaaan! After teaching the kiddies sane syntax, you revert to this unspeakable line-noise? Aw.... maaaan...!

Well, I'll look at it more later, but you seem to be heading in the "wrong direction" for me.

Best,
Frank


Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Random Examples
« Reply #2 on: February 10, 2010, 03:20:25 AM »
Actually, that was an error. When I started writing these first, I was using my CCALL macro which actually does automatic stack clean-up. Then I thought for the sake of the tutorial I would drop the macro until later and have the reader write the macro itself. I then went through and started "fixing up" the code with stack clean-up, so you've just found one one of the place I missed (nice catch). I did a quick scan of the files and fixed a lot of those types of errors (there were several actually). I also noticed that when I reintroduced the CCALL macro I forgot to use it on exit in Ch07, that's also fixed.

PTR was upon request and was working it's way towards a directive based "type system" I've shown before. I find it a little funny though that you think PTR is where I went too far, not Report, not Die, but PTR lol.

I've uploaded the repaired version, if you see anything else, let me know. I appreciate the feedback. :)

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Random Examples
« Reply #3 on: February 10, 2010, 06:54:31 AM »
I wondered if that was a "remnant" from a macro, possibly one that cleans up the stack, or not, depending on the calling convention defined...

I find it a little funny though that you think PTR is where I went too far, not Report, not Die, but PTR lol.

I didn't say you went too far, I said you went in the wrong direction! Merely a matter of opinion, of course - a fairly strongly-held opinion on both sides, I notice. :)

I don't have any problem with "Report" or "Die" - those seem useful, "PTR" not-so-much.

I regularly use a "say" macro, and a "checkerror" macro - both of which just do "setup" and call a subroutine, which must be there if the macro's going to work. The "advantage" to them is that they put the "text" parameter off in .data (should be .rdata, really) and give it a cryptic label that I don't have to remember when I want to spit out "we died here" (or "we got here without dying"!). Pretty much the same as you've got. (why do you zero eax in "Die"? It might have a valid exit code...). My "checkerror" spits out some text - cribbed straight from the comments in "errno.h" - as well as the supplied "we died here", and jumps to a supplied label (which also must exist). In practice, that label has almost always been "exit" (where we arrive with a busted stack, usually), but in theory would allow a "retry".

I'm fooling with a "findneedle" macro:

findneedle [header_pos], [header_len], "From:"
jz big_trouble
;save what we found, followed by:

findneedle [from_pos], [from_len], "viagra"
jz delete_message

This is, as we speak, deleting spam from the clax inbox! :)

So I'm not "against" macros. I have "reservations" about teaching 'em to newbies. Teaching them how to write and use macros, as you apparently have in mind, is fine - greatly needed! Teaching 'em to use macros "instead of assembly language", like... well, naming no names... seems like a bad idea to me. Although, it seems to work well for some people.

Here's an example using my "yanetut" macros. Sounds like "yet another newbie educational(?) tutorial", but it stands for "you are not expected to understand this" (a comment in the Linux code, for those who don't recognize it). Intended as a joke on... a tutorial that purports to teach assembly language by "hiding the hard parts".

Code: [Select]
; nasm -f elf hw2uyane.asm
; ld -o hw2uyane hw2uyane.o

%include "yanetut.inc"
    putstring "Please tell me your name?  "
    getstring  79,name
    putstring "Hello, "
    putstring name
    putstring "! Welcome to Linux uhhh... Assembly!", linefeed
    putstring "BTW, the answer is "

   ; warning, assembly language!
    mov ecx, 42
    mov ebx, 1
    add ebx, ecx
    ; HLLp, I can't read this part!!!

    putnumber ebx
    putstring ", not "
    putnumber ecx
    putstring ". Deep Thought was off-by-one.", linefeed

    depart victorious

As you can see, I couldn't resist adding some assembly language, but the basic "hello2u" doesn't have any of the "hard parts" showing at all. I suppose I should have added a build script, to keep 'em from having to type "nasm" and "ld" with those complicated command lines. You can help me find *my* bugs, if you want to waste the time, but it's intended as a joke...

Best,
Frank


Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Random Examples
« Reply #4 on: February 10, 2010, 03:11:16 PM »
These examples were only meant to be incremental demos showing vague ideas as I was in my plotting stage. I was actually in the process of writing a Ch10 - a VERY simple mathematical expression compiler. In hindsight, there are probably a few other chapters that should be before the expression compiler, but that was the direction of my thought process. I really wish I could find them right now as I did multiple example collections, some used macros for simplification, some were more heavily math based, and one collection was totally INT 80 focused. If I can pull them together I'll post an update here but I have all that stuff scattered around. The reason I went with this collection in the end was because it was covering the widest range of programming tasks, and the syntax seemed to be accepted even by some of my MASM friends. That was a big issue for me as I've always been given a rep for having a "completely illegible coding style", I think it's the odd use of STRUC's for things like parameters and locals which confuses people. lol

I skimmed over the code you posted and it vaguely reminds me of my old TI-Basic syntax macros (PRINT, INPUT, etc.) I used when trying to teach a classmate assembly from a TI-83 Plus BASIC background. With him we started with a macro generated syntax which mimicked what he already knew, then slowly worked our way away from the macros to a syntax which looked much more like Ch09 (I only had two months to work with him). I understand your "reservations" however the idea was that the reader would actually develop every part of the code, even the macros. This would allow them to be able to design development aids at will. You'll notice a few of the macros change in their capabilities as the chapters would progress. As a need presented itself, the reader would extend the macro to suit their need. I don't see any really apparent errors (haven't tried to build it yet) although some parts do kinda confuse me, like you push bytes then pop dwords in your procedures.

As a side note, Appendix B from my tutorial was completed and I had decided to post it on my site as a separate article in it's own right. It's called Fundamenals of Development, although it's more about the Process of Development... There have been some punctuation issues brought up and YES the code is intentionally flawed (it's to introduce the software validation process ;))

About Bryant Keller
bkeller@about.me

Offline Mathi

  • Jr. Member
  • *
  • Posts: 82
  • Country: in
    • Win32NASM
Re: Random Examples
« Reply #5 on: February 10, 2010, 06:35:01 PM »
Great examples, Especially the xlib ones.

I am using Ubuntu 9.10  64 bit, and i had to do the following things to get these examples compiled.

1)  Install    libc6-i386  and libc6-dev-i386   ( otherwise gcc/ld will complain while linking).

sudo apt-get install libc6-i386
sudo apt-get install libc6-dev-i386

2)  add the -m32 switch to the CFLAGS in Makefile. (informs gcc/ld to link for 32bit)
like,

CFLAGS=-Wall  -m32


3) the version of nasm which comes by default in Ubuntu 9.10 is   Nasm v 2.05.01

ex08.asm and ex09.asm didn't get compiled in version 2.05.01

__%{1}__  was evaluating to empty.  :(  (in macros  CCall and StdCall)  (not in all instances though)

I manually upgraded to 2.07 and was greately relieved to see that it was working in 2.07 :)

Regards,
Mathi.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Random Examples
« Reply #6 on: February 10, 2010, 07:21:12 PM »
They were never meant for 64-bit systems, glad to see you got it working.

Seems I remember something about the __%{1}__ error, I believe I had a work-around at one time but it escapes me. That's one of the reasons that, while I was working on NASM32/NASMX I would keep a local mirror of the NASM repo for testing. Things get fixed and with NASMX we wanted stuff to be as portable between versions as possible.

I find it hard to believe the Ubuntu repo's are out of date, I wonder who manages that.....

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Random Examples
« Reply #7 on: February 11, 2010, 05:59:04 AM »
"... like you push bytes then pop dwords in your procedures."

Oh, you mean this stuff?

write_stdout:
    push byte 1
    pop ebx
    push byte 4
    pop eax
    int 80h
    ret

Just a shorter (but slower) way to "mov eax, 4", etc. Learned it from Konstantin Boldyshev's "asmutils" macros. I'm not too crazy about it. That's why it's "hidden away". :)

Mathi raises a really good point:

" add the -m32 switch to the CFLAGS in Makefile. (informs gcc/ld to link for 32bit)"

If you've got a 64-bit system, your tools are expecting to build 64-bit code. If you feed 'em 32-bit code, the error messages are quite confusing! Unless I'm mistaken, the option if you're invoking ld directly is "-melf_i386". This needs to be blabbed around so the kiddies know what to do about it, since 64-bit is becoming common, and most available examples are 32-bit. Thanks for that 64-bit example, Mathi! Sorry you had the problem with the macro. It *is* fixed now, right?

I'll take a look at that "Fundamentals of Development". I need it. I understand "assembly language" pretty well, but I'm not much of a "programmer". This is becoming obvious as I try to do something "serious". Getting lost in my own spaghetti. I should've developed better habits!

Best,
Frank


Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Random Examples
« Reply #8 on: February 11, 2010, 07:38:24 AM »
"... like you push bytes then pop dwords in your procedures."

Oh, you mean this stuff?

write_stdout:
    push byte 1
    pop ebx
    push byte 4
    pop eax
    int 80h
    ret

Just a shorter (but slower) way to "mov eax, 4", etc. Learned it from Konstantin Boldyshev's "asmutils" macros. I'm not too crazy about it. That's why it's "hidden away". :)

Yea, that's the code I was talking about. I've honestly never seen anyone do that, though most people I know are trying to optimise for speed.

Mathi raises a really good point:

" add the -m32 switch to the CFLAGS in Makefile. (informs gcc/ld to link for 32bit)"

If you've got a 64-bit system, your tools are expecting to build 64-bit code. If you feed 'em 32-bit code, the error messages are quite confusing! Unless I'm mistaken, the option if you're invoking ld directly is "-melf_i386". This needs to be blabbed around so the kiddies know what to do about it, since 64-bit is becoming common, and most available examples are 32-bit. Thanks for that 64-bit example, Mathi! Sorry you had the problem with the macro. It *is* fixed now, right?

I've updated the example to include a file called Makefile.64 which has the changes that Mathi mentioned.

I'll take a look at that "Fundamentals of Development". I need it. I understand "assembly language" pretty well, but I'm not much of a "programmer". This is becoming obvious as I try to do something "serious". Getting lost in my own spaghetti. I should've developed better habits!

That document is a REALLY simplified overview. I didn't cover things like event planning documents, execution graphs, and other common organisation stuff. If you are getting lost in your code, then chances are what you need to try using are Use-Case documents, Requirements Documents, and Event Planning Documents.

The Use-Case describes the user's interaction with your software, the requirements document describes how your software will interact with the computer (what storage, networking, or hardware interfaces you need) and the Event Planning Document is a table which contains three columns; the first being the name of each of the events and procedures in your source file, the second being the description for each of these procedures, and the third column being pseudo-code describing your idea of how to implement the procedure/event. An event planning document is usually written for each file in your project, each file generally contains similar or related routines and events anyway.

For small projects, doing these can be a pain, but for larger projects it'll keep you from getting lost. Also, I've found that if I write these documents for a project, I not only spend less time debugging, but I spend less time coding as well. Even though documenting all this stuff seems like a waste of time, the organisation it lends to your project makes things move along so much more quickly.

About Bryant Keller
bkeller@about.me

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Random Examples
« Reply #9 on: February 11, 2010, 03:40:36 PM »
Frank,
I thought I would upload a PDF version of an event planning document I use.

http://assembly.ath.cx/files/epdoc.tar.gz

About Bryant Keller
bkeller@about.me

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Random Examples
« Reply #10 on: May 16, 2011, 05:22:28 AM »
UPDATE BY REQUEST:
I don't have the assembly.ath.cx host anymore, so here is the random examples. Sorry that I let the link go dead without updating earlier.

Regards,
Bryant Keller

About Bryant Keller
bkeller@about.me