linux-assembly.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: linuxassembly@evobsyniva.com
To: linux-assembly@vger.kernel.org
Subject: Re: Does anyone code in assembler today?
Date: Thu, 18 Sep 2003 09:00:41 -0400	[thread overview]
Message-ID: <oprvo43fxwlmcbdf@smtp-server.woh.rr.com> (raw)
In-Reply-To: <200309171020.17639.jko@save-net.com>

> My release of a few days ago resulted in three responses.

Could it be that few people use assembly language debuggers?

I've always been surprised at the number of people who talk about using one 
on this list.  I figured people didn't use them and debugged using other 
methods.  When I first started assembly I used DOS debug to debug things, 
but as soon as I used graphics modes it became useless, and so I learned 
new ways to debug.  Many of my programming mistakes are obvious as soon as 
I run the executable, and so I know exactly what to fix.  Others require 
tossing in a few print-type macro calls so that I can see what code is 
being executed and what isn't (I can leave these in the code, and enable or 
disable the macro when compiling).  Sometimes I use another macro to print 
out a register's contents.  I've got code that prints a register dump, so 
if I need to see a lot of registers I'll just insert a 'cli' or something 
that will segfault.  This code also keeps track of what functions are 
executing in a stack structure and prints it out (also can be disabled at 
compile time) and this about eliminates the need to track execution.  If 
things are really bad I'll write out a section of memory to a file and 
examine it with a hex editor, but that seldom happens.  I've just always 
debugged this way, and it's worked fine.  I really wouldn't know what to do 
with a debugger.

> So.. maybe we are a small community which is difficult to join?

It could be.  Assembly programmers look at my code and freak out over the 
vast number of macro calls and such, and declare it 'not real assembly'.  
Consider that anything to help you get started in assembly language is 
going to be written by these same people.

If you're debugging a piece of code that segfaults, it'll be quite easy to 
do this:

status "first"
mov eax, [ebx]
status "second"
mov edx, [ecx]
status "third"
div dword [ebp+12]
status "fourth"

If you run the code and it prints...

crap:/home/sloop/$ ./program
first
second
Segmentation Fault
crap:/home/sloop/$

...you pretty much know where to look for the problem.  Yet no one likes to 
use macros for anything.  People getting into assembly language are never 
introduced to using macros to simplify programming, and when you can't so 
much as write five lines of code without a mistake (common for beginners) 
adding in more code to debug it will likely just result in even more bugs.  
Beginners need to be encouraged to use macros, at least as a stepping stone 
to help them in the beginning.

But macros are good for everything.

http://www.evobsyniva.com/softer/archive/softer-118.tgz

file: /src/macros.nasm  - 63 macros, without which Softer wouldn't exist at 
all.

9 macros create if/then type statements, 6 for do/loop, and a skip/land 
(just jumps over a block of code) and they almost always produce the same 
code I would have written without them.  There are a couple cases they 
won't, usually I use them anyway because they do one very important thing:  
they keep the code readable.  When you've got a hundred different branches 
in a piece of code, it's impossible to give them all a meaningful label, 
and you can't look at a jump instruction and tell if it goes forwards or 
backwards, and how far.  When you use if/elseif/else/endif, you just follow 
the indenting and there's your answer.

Case in point:  /pjasm/*.asm
I wanted to write these in pure assembly language without any macros just 
for fun.  By the time I was finished I was having a heck of a time 
debugging them because I simply couldn't keep track of how they worked in 
my head.  Lack of indenting and nested code structures makes any 
programming language extremly difficult.  I couldn't follow code I wrote 
ten minutes earlier.

print 2, "yes, this macro does what you think"  -- when you're debugging 
you don't want to have to declare the string here, write code there to do 
the system call, and clean up the mess afterwards.

3 macros that read/write blocks of data fully checking system call return 
values, good for debugging and quick programs you'll only use once, I have 
the same code in functions in a different file if I plan to use it in a 
real program.

enter/leave macros.  These aren't the enter/leave instructions, I couldn't 
figure out what they did, so I made macros with the same name.  They work 
like ' enter "easy.asm - easyprint" ' and just db the string and call a 
function that adds the address of the string to a stack, leave pops the 
address off the stack.  When I get a register dump from a trap macro or a 
system signal, I get this:


Signal 11 recieved.

EAX: 00000000  EBX: 00000002  ECX: 08052455  EDX: 000002D4
ESI: BFFFFC50  EDI: 0805272A  EBP: BFFFFB44  ESP: BFFFFB24
EIP: 08048C30  EFLAGS: 00000000 00000000 00000010 00000110                  
                                                                  ..OD   SZ 
A P C
Debugging Stack:

Softer 0.118
startup.asm
 -- framebuffer check
easy.asm - easyprint
!!! Signal Trap

Happy debugging!

Under the section "Debugging Stack"  "Softer 0.118" is the main.asm file 
that starts the program.  It called startup.asm which was in the middle of 
the framebuffer check when it called easy.asm's easyprint function.  At 
this point a signal 11 was recieved (see top line), and thus we got this 
error message.

It'd have been impractical without macros.  I'd just have a segmentation 
fault message and have to guess where the problem was.

Now to assembly language itself.  Why do we only allow one instruction on a 
line of code?  Take the example below for example.  Once you read the 
contents of the first if section, you basically know what the next three 
do, since you can easily see they're at least almost the same.  Do this one 
instruction on a line and you can't even fit it all on the screen.  You 
also have one long stream of code all of which basically looks the same 
except for a blank line here and there, but like this it has a certain 
shape that can be recognized at sight, making this function easier to find 
in a file.

The third line, all three instructions work towards a single goal, it makes 
sense to group them together.  The fifth line all six instructions select 
the correct video page, makes sense to group them as well.

softer_outof_video
  # Save Softer's video in RAM.
  mov ebx, [display_mode]; shl ebx, 4; add ebx, ram_counts
  if dword [ebx+0], 0, nz
    mov dx, $3CE; mov al, $04; outb; mov dx, $3CF; mov al, $00; outb;
    mov edi, softer_mem_store + $00000; mov esi, [video_ram_pointer]
    mov ecx, [ebx+0]; rep; movsd
  endif
  if dword [ebx+4], 0, nz
    mov dx, $3CE; mov al, $04; outb; mov dx, $3CF; mov al, $01; outb;
    mov edi, softer_mem_store + $10000; mov esi, [video_ram_pointer]
    mov ecx, [ebx+4]; rep; movsd
  endif
 if dword [ebx+8], 0, nz
    mov dx, $3CE; mov al, $04; outb; mov dx, $3CF; mov al, $02; outb;
    mov edi, softer_mem_store + $20000; mov esi, [video_ram_pointer]
    mov ecx, [ebx+8]; rep; movsd
  endif
  if dword [ebx+12], 0, nz
    mov dx, $3CE; mov al, $04; outb; mov dx, $3CF; mov al, $03; outb;
    mov edi, softer_mem_store + $30000; mov esi, [video_ram_pointer]
    mov ecx, [ebx+12]; rep; movsd
  endif
ret

> Of course, the argument is that hardware is getting faster
> and speed is no longer an issue.  Also, memory is cheap
> and big bloated programs are best because they get into the
> market quickly.  It is much easier to train programmers
> in the newer languages and todays tools isolates everyone
> from knowing much about hardware or hex.

I never see large programs (compared to other non-assembly programs) 
written in assembly language.  In it's natural state, assembly isn't well 
suited for large projects.  There's the madness of 10,000 labels I 
mentioned earlier from every single control branch and little temporary 
variable.  Etremely long source files since every operation is broken down 
into 6 steps, each on it's own line.  Any large program has to be split 
into seperate files to be managable (scrolling down 18,000 lines to get to 
the function you're looking for just isn't acceptable), but with NASM, 
every variable shared between files has to be global'd in the one file and 
extern'd in the other, and seeing the associated compiler errors gets old 
after a while, as does starting a new source file and copy&pasting the 
externs over for every shared variable you're going to use.  Worse yet you 
can't global on the same line you declare the variable.

I fixed this kind of with /tools/vernix.pl..  You make your global varibles 
with code line "vernix global_variable" and when compiled, these lines are 
looked for..  The word vernix is macro'd to null so it doesn't affect NASM, 
and a header file is created for each source file which contains global 
statements for each vernix variable in that file, and extern statements for 
each vernix variable in all the other files but that one (if you extern a 
global nasm gets upset).  It works pretty well.

In the end, I've got assembly pretty easy so I can program in it, but the 
problem is that beginners have to go and duplicate all the work I did 
above.  I can see why people would look at assembly and think it's too 
difficult to be worth the effort put into it.

> So.. i wonder if it would be better to port some old DOS
> libraries to work under X or stay with the console?

Stay away from X.  Everyone secretly hates it, it's the only thing that 
makes them have to reboot their linux box.  If you just want to do VGA 
graphics modes Softer contains all the code you need to switch modes in 
src/video.asm, and the stuff you need to do because of this in console.asm, 
switcher.asm, signal.asm, keyboard.asm, ... most the other files.  It's 
complicated, you have to make up for Linux's lack of a VGA driver and do 
all the multitasking of the display device between your program and the 
other programs yourself.  But it's workable, I even figured out all the 
race conditions although one took me like a year.

BTW, I have screenshots now:  
http://www.evobsyniva.com/softer/captures.html  VGA modes in Linux are 
really quite nice, much nicer than GUI windows in X.

 

  parent reply	other threads:[~2003-09-18 13:00 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-09-11 11:01 I/O Rafael Diniz
2003-09-11 11:07 ` I/O Rudolf Marek
2003-09-11 13:21 ` I/O peter w krause
2003-09-15 14:30   ` Assembler Tools jeff
2003-09-16  2:15     ` Rafael Diniz
2003-09-17 17:20     ` Does anyone code in assembler today? jeff
2003-09-17 18:20       ` myrkraverk
2003-09-18  6:31       ` Frederic Marmond
2003-09-18  7:57         ` peter w krause
     [not found]           ` <3F696702.9040407@eprocess.fr>
2003-09-18 10:46             ` peter w krause
2003-09-18 16:10         ` jeff
2003-09-21 10:19           ` Maciej Hrebien
2003-09-21 12:05             ` Stephen Satchell
2003-09-22  9:53           ` peter w krause
2003-09-18 13:00       ` linuxassembly [this message]
2003-09-16  2:42 ` Art of Assembly Is Real! Randall Hyde
2003-09-16  6:54   ` Brien B.
  -- strict thread matches above, loose matches on Subject: below --
2003-09-18 12:48 Does anyone code in assembler today? Jason Roberts

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=oprvo43fxwlmcbdf@smtp-server.woh.rr.com \
    --to=linuxassembly@evobsyniva.com \
    --cc=linux-assembly@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).