You are not logged in.

#1 2008-09-14 21:03:12

mrbug
Member
Registered: 2007-07-17
Posts: 221

[SOLVED] ASM basics

My brother is taking a beginning programming class, and the teacher has deemed it appropriate to assign homework that involves programming in assembl(y/er) using debug.exe (in dos/win).

He needs to prompt the user to enter his or her name one character at a time, and then print it in two different ways:
1. u<tab>s<tab>e<tab>r

2.
u
 s
  e
   r

I know that #1 involves printing the character and then a tab character and #2 involves printing the character and then a line feed character (but not carriage return!).

However, I can't figure out how to read the characters one at a time. It's been too long since I've played with asm. Can someone give me some pointers/hints? I'll pass the hints along to him in such a way that he still learns from it.


The class is supposed to cover VB, by the way.

Last edited by mrbug (2008-09-17 17:28:32)


dvdtube - download all uploads from a YouTube user and then optionally create a DVD.
(Regular version AUR link / SVN version AUR link)

Offline

#2 2008-09-14 21:28:31

deltaecho
Member
From: Georgia (USA)
Registered: 2008-08-06
Posts: 185

Re: [SOLVED] ASM basics

It's been a while since I've done anything with VB, and I don't remember the exact syntax to separate the characters of a String, but this algorithm should work:
1) Initialize an integer called "spaces" to 0 (this will hold the number of spaces before each character)
2) Create a for loop that initializes an integer "c" to 0 and increments it by one each loop
   2.a) Print the String's character at index [c], preceded by the number of spaces denoted by integer "spaces"
   2.b) Increment "spaces" by one
   2.c) If the value of "c" is >= ( the String's length - 1 ), terminate the loop

As far as the actual syntax for accomplishing that goes, I would have to boot into Windows and play around with Visual Studio for a while, which I don't really want to do unless you really can't figure it out and nobody else comes along who can help more.


Dylon

Offline

#3 2008-09-14 21:41:10

mrbug
Member
Registered: 2007-07-17
Posts: 221

Re: [SOLVED] ASM basics

Oh, sorry.. This is for assembly/assembler (whichever it's called...), not VB. The class is supposed to be VB, but the assignment is ASM.


dvdtube - download all uploads from a YouTube user and then optionally create a DVD.
(Regular version AUR link / SVN version AUR link)

Offline

#4 2008-09-14 22:05:15

deltaecho
Member
From: Georgia (USA)
Registered: 2008-08-06
Posts: 185

Re: [SOLVED] ASM basics

That's alright.  I don't know anything about ASM, but the algorithm should still be good.


Dylon

Offline

#5 2008-09-15 23:46:50

e_tank
Member
Registered: 2006-12-21
Posts: 80

Re: [SOLVED] ASM basics

so this teacher of an intro to programming class, which will primarily be using vb, wants the students to work in x86 assembly using debug.exe??  that's insane, what is he/she thinking!  not that i'm against the idea of learning how a processor works and an assembly language first, z80 asm was the second language i learned and it made learning c/c++ easier later on, but x86?  i think a risc or more basic cpu would be a more appropriate starting point, but even so forcing them to use debug.exe instead of a real assembler is just stupid.  i'm sure it will frustrate more students than it will help.

anyway here are some resources for you:
debug.exe tutorial
forum post with some useful info and a link to a list of interrupt services for dos
another short debug.exe tutorial
2 page x86 instruction set ref sheet

writing code in debug.exe is very awkward, mainly because it doesn't allow/resolve labels and you can't add instructions between ones you've already written (at least i don't think you can), so it might be easier to edit code in text files and paste what you write into debug.exe.  you could for example, write your code with labels in one text file, say txt1, then when you're done copy and paste the code into a new text file, txt2.  in txt2 removes the labels and change all instructions referencing labels to a place holder number > 100 (your codes starting point).  it will make it easier if you use the same number for a particular label.  then run debug.exe, give command 'a' to start entering assembly code and paste in your code from txt2.  when the paste finishes press enter and use the 'u' [address start] [address end] command to view your code so you can find the actual addresses for each label.  change your code in txt2 to use the correct addresses for each label you reference, then exit and rerun debug.exe pasting in the new and hopefully final code.  remember though, if you make a mistake and have to add instructions or change an instruction to another that has a different opcode lengh you may invalidate some labels you've entered in txt2 and will have to update them again.

i've worked in many different assembly languages before but never much in x86, i can read it fine for the most part but i've only memorized the very basic instructions so i can't write my own all that well.  with that said below is one possible way to accomplish the first problem.  it runs but there might be something wrong with it as it only runs once, if i tell debug.exe to run it again it exits after reading in the name.  anyway it should give you an idea of what you should be doing and how to solve the second problem (which i don't mind writing as well if requested)

here's how i first wrote it, with labels (all numbers in hex)

    mov    dx,msg
    mov    ah,9        ; print out instructions
    int    21        ;  to the user
    mov    bx,data        ; bx = address to store name str to
    sub    si,si        ; si = user name str index
lget_name:
    mov    ah,1        ; get a char
    int    21        ;  from the user
    cmp    al,1f        ; if char ascii below '!'
    jb    lget_name    ;  ignore and continue
    cmp    al,7a        ; if char ascii above 'z'
    ja    lget_name    ;  ignore and continue
    mov    [bx+si],al    ; add char to name str
    inc    si        ; update name str len
    cmp    al,24        ; if char != '$' (this makes sure str is $ terminated)
    jne    lget_name    ; continue
    mov    cx,si        ; cx = name str len
    mov    di,si        ; di = tab name str index
    sub    si,si        ; si = name str index (of the name entered)
    mov    al,0d        ; prepend the tab name str with 0d+0a
    mov    [bx+di],al    ;  to print on the next line
    inc    di
    mov    al,0a
    mov    [bx+di],al
    inc    di
ltab_name:
    mov    al,[bx+si]    ; copy char from name str
    mov    [bx+di],al    ; to tab name str
    inc    di
    mov    al,9
    mov    [bx+di],al    ; add the tab
    inc    di
    inc    si
    cmp    cx,si        ; if name str len > name str index
    ja    ltab_name    ;  continue creating tab name
    mov    dx,bx        ; put address of tab name in dx
    add    dx,cx        ;  this string is also $ termnitated as
    mov    ah,9        ;  we copied the $ from the source name str
    int    21
    ret
msg:
    db    "enter your name, press sign when done",0d,0a,"$"
data:
    db    "data buffer for strings starts here, this msg is just for your ref$"

and here is the code after i removed and resolved the labels, the code starts at address 100 (all numbers in hex).  this code can be cut and pasted directly into debug.exe and ran.

    mov    dx,0147
    mov    ah,9        ; print out instructions
    int    21        ;  to the user
    mov    bx,016f        ; bx = address to store name str to
    sub    si,si        ; si = user name str index
    mov    ah,1        ; get a char
    int    21        ;  from the user
    cmp    al,1f        ; if char ascii below '!'
    jb    010c        ;  ignore and continue
    cmp    al,7a        ; if char ascii above 'z'
    ja    010c        ;  ignore and continue
    mov    [bx+si],al    ; add char to name str
    inc    si        ; update name str len
    cmp    al,24        ; if char != '$' (this makes sure str is $ terminated)
    jne    010c        ; continue
    mov    cx,si        ; cx = name str len
    mov    di,si        ; di = tab name str index
    sub    si,si        ; si = name str index (of the name entered)
    mov    al,0d        ; prepend the tab name str with 0d+0a
    mov    [bx+di],al    ;  to print on the next line
    inc    di
    mov    al,0a
    mov    [bx+di],al
    inc    di
    mov    al,[bx+si]    ; copy char from name str
    mov    [bx+di],al    ; to tab name str
    inc    di
    mov    al,9
    mov    [bx+di],al    ; add the tab
    inc    di
    inc    si
    cmp    cx,si        ; if name str len > name str index
    ja    012f        ;  continue creating tab name
    mov    dx,bx        ; put address of tab name in dx
    add    dx,cx        ;  this string is also $ termnitated as
    mov    ah,9        ;  we copied the $ from the source name str
    int    21
    ret
    db    "enter your name, press sign when done",0d,0a,"$"
    db    "data buffer for strings starts here, this msg is just for your ref$"

Offline

#6 2008-09-17 17:27:30

mrbug
Member
Registered: 2007-07-17
Posts: 221

Re: [SOLVED] ASM basics

Wow, that actually makes a lot of sense! Combining registers (that's what "mov [bx+di,al" does, right?) was one of my biggest questions.

Thanks for the links; I did actually find the codeguru one earlier and it helped a bit. My brother was able to figure out how to print predefined data in the two different ways, but it looks like there was a bit more code required to get those letters from user input. It shouldn't be too hard to modify the code to change from tab to lf.


I really want to learn asm, and seeing someone do something with it helps alleviate the feeling of "this is ridiculous!"

The teacher really has it wrong -- he's apparently going to teach them some C before moving onto VB. Thanks for your help! Now I can help him...


dvdtube - download all uploads from a YouTube user and then optionally create a DVD.
(Regular version AUR link / SVN version AUR link)

Offline

Board footer

Powered by FluxBB