ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
While self-learning assembly language (standard 80x86 syntax, using TASM as compiler) I can't seem to get what I'm doing wrong in an exercise taken from a book.
The exercise is like this: reverse the letters of the string like in the following examples:
qwer -> wqre
qwert -> wqret
Aka invert each 2 letters.
Here is my code:
Code:
DOSSEG
.MODEL SMALL
.STACK 100h
.DATA
MAXIMUM_STRING_LENGTH EQU 1000
StringToReverse DB MAXIMUM_STRING_LENGTH DUP(?)
ReverseString DB MAXIMUM_STRING_LENGTH DUP(?)
i dw ?
.CODE
mov ax,@data
mov ds,ax
; read string:
mov ah,3fh
mov bx,0
mov cx,MAXIMUM_STRING_LENGTH
mov dx,OFFSET StringToReverse
int 21h
;if nothing is read, end program
and ax,ax
jz Done
mov cx,ax
push cx
mov bx,OFFSET StringToReverse
mov si,OFFSET ReverseString
;if only 1 character is read:
cmp cx,1
jne NoSingleChar
mov al,[bx]
mov [si],al
jmp Print
NoSingleChar:
mov i,1
inc si
MainLoop:
mov al,[bx]
mov [si],al
inc bx
dec si
mov al,[bx]
mov [si],al
inc bx
add si, 3
add i,1
cmp cx,i
je Print
inc i
cmp cx,i
jne MainLoop
dec si
mov al,[bx]
mov [si],al
Print:
pop cx
mov ah,40h
mov bx,1
mov dx,OFFSET ReverseString
int 21h
Done:
mov ah,4ch
int 21h
END
It works for an odd number of letters, but not for an even number.
E.g. for qwert it shows tqre and I can't figure out why it does that.
What I also don't get... the AX register, which is supposed to contain the number of characters read after the 3fh dos function, according to the debugger, contains the number of characters +2... Aka for qwer it will hold 6, why is that?
Anyway, the main question: what am I doing wrong? Any suggestion or idea is welcomed.
Distribution: slackware64 13.37 and -current, Dragonfly BSD
Posts: 1,810
Rep:
While I find it odd posting Dos questions on the Linuxquestions forum I'll try to be helpful. A quick look at your code seems rather confused - this is after all a simple problem involving an increasing source and decreasing destination index - one initialised to the string beginning the other to the target start + string length-1. Try to map this process out into pseudo code and it should be easy to translate this to assembler.
I'm not familar with TASM but a powerfull tool is always a single stepping debugger - like Dos's DEGUG (or the more powerful SYMDEB - CODEVIEW came later from Micrsoft). TASM may have an equivalent allowing symbolic debugging. You can then step through your code examining registers and memory locations to easily spot mistakes.
As to the interrupt returning unexpected values - perhaps the string length includes a CR + LF on the end of the string - just a guess but debugging should make this obvious.
While I find it odd posting Dos questions on the Linuxquestions forum I'll try to be helpful. A quick look at your code seems rather confused - this is after all a simple problem involving an increasing source and decreasing destination index - one initialised to the string beginning the other to the target start + string length-1. Try to map this process out into pseudo code and it should be easy to translate this to assembler.
I'm not familar with TASM but a powerfull tool is always a single stepping debugger - like Dos's DEGUG (or the more powerful SYMDEB - CODEVIEW came later from Micrsoft). TASM may have an equivalent allowing symbolic debugging. You can then step through your code examining registers and memory locations to easily spot mistakes.
As to the interrupt returning unexpected values - perhaps the string length includes a CR + LF on the end of the string - just a guess but debugging should make this obvious.
Good Luck with this.
This is what written at the page top (emphasis is mine):
Quote:
This forum is for all programming questions. The question does not have to be directly related to Linux and any language is fair game.
First of all,I got it fixed... it was related to the number of characters, the weird +2 value that cx had.
Yes, I am aware it is a Linux forum, and that it's the non-*nix section :P
You guys always helped me out, wether with programming or linux questions, so it didn't seem strange to me.
Plus, I'm learning the DOS-version of assembly only because you can find more resources about it, my final goal shall be, of course, some linux kernel device drivers and other fun stuff :P
How was that quote... "don't you miss the days when a man was a man and wrote his own device drivers?" or something like that
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195
Rep:
Quote:
Originally Posted by H_TeXMeX_H
yeah, back when devices were connected via serial ports and used standard interfaces
This is what we still do in Linux... since 1970-ies we have /dev/ttyS0 and that has never changed since.
It was a (bad) habit introduced in DOS(*) that hardware was addressed immediately from any program, and yes, in some way you could call
Code:
mov ax,1F
out 378,ax
a standard way to talk to a serial device.
(*) Well maybe it was not really introduced in DOS, we had the AppleII and the Commodore etc before that, but DOS was the first platform were [commercial] programs became available in such vast quantities and still using those awkward techniques. Although the intention of the DOS architecture was to do it well-behaved thru a BIOS function.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.