Author Topic: Help Needed  (Read 22998 times)

Offline grvtiwari

  • Jr. Member
  • *
  • Posts: 12
Re: Help Needed
« Reply #15 on: June 10, 2012, 08:40:22 AM »
I am referring a book on Assembly Language on LInux. It recommends us to use a "io.mac" and "io.o" file for complex input output procedure(in fact, every book I came across, pushed a io.o file  to use it to reduce the complexicity. This upsets me. When I am already ready to bang my head to learn the most complex low level language, why there is a need to hide any more details. Show me how exactly their read and write function works. ). I have a query regrading their procedure in io.o file. For example, there is a call
Code: [Select]
PutStr prompt_msgl ; request first number
Getint CX ; CX = first number
PutStr  prompt_msgl; request second number
Getint DX ; DX = second number

I understand how PutStr works. But I do not understand how this GetInt Works. Wait a minute I think I guessed how this GetInt works. There is no call instruction before GetInt which means it must be a Macro. Let me look up there. Then, What this means

Code: [Select]
%macro  PutInt  1
or this

Code: [Select]
%macro  GetInt  1

%ifnidni %1,AX

        push    AX

        call    proc_GetInt

        mov     %1,AX

      pop     AX

%else

        call  proc_GetInt

%endif

%endmacro

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help Needed
« Reply #16 on: June 10, 2012, 06:14:51 PM »
Sivarama Dandamudi? Sounds like his work. I haven't read his book, but I downloaded the example code including "io.mac" and "io.o". I haven't got source code for "io.o", and I understand it isn't in the book either... but we can disassemble it... It looks to me like Dr. Dandamudi originally wrote this for dos and converted it for Linux. It looks to me like he died before he was completely finished. In the macro you show, for example, "push ax"... That's a "legal" instruction, and works, but we'd get better performance if the stack were kept aligned at 4 bytes (for 32-bit code). There are a few 16-bit registers used in io.o, too. Not nice to speak ill of the dead, but this "isn't the way I would have done it."...

I agree with you about "hiding the details"! There's a reason this is (often!) done - there's a limited amount of time available in a formal "course", and if you show/teach/learn all the nitty-gritty details, you won't get very far before the end of the course! If the goal is to "obtain the program" (or just to "pass the course"), it makes sense to do this. If the goal is to "learn assembly language", it seems a shame to hide away the "good stuff". Inevitably, there's a "black box" at the end which we have to "just use" without understanding how it works (int 80h, for example), but I like to "see" as much as possible. Just my opinion...

Is there a "question" in this? Do you want to see the disassembly of "proc_GetInt"? Same idea as what you do, but he handles invalid input (and overflow) better.

Sorry I "did your homework" too much. I learn "by example" better than by "RTFM", so that's how I try to explain things. I don't know exactly what "hint" (or hints) you need, or I would limit it to that. "Just call printf" (or "just use io.mac/io.o") doesn't seem like enough. I'll try...

Best,
Frank


Offline grvtiwari

  • Jr. Member
  • *
  • Posts: 12
Re: Help Needed
« Reply #17 on: June 10, 2012, 10:31:21 PM »
Yes. It is the same book. I do not want to disassemble the code. Actually, I want to understand how he passed the parameters in GetInt AX. I mean it is not call by value(through registers) or through referance(through stack). And what %1 means here ?

That's all I want to know. I have a very bad habit. I want to code everything without any io.o . I mean when I say that I can code in assembly, then I should really be able to do that. After 10 years, I do not wish to seek help of a io.o to do simplest thing. It hurts the programmer in me.

Thanks. I will mention exactly what I require.
And I was expecting some comments on my previous number to string program.

Thanks.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Help Needed
« Reply #18 on: June 11, 2012, 01:17:28 AM »
I am referring a book on Assembly Language on LInux. It recommends us to use a "io.mac" and "io.o" file for complex input output procedure(in fact, every book I came across, pushed a io.o file  to use it to reduce the complexicity. This upsets me. When I am already ready to bang my head to learn the most complex low level language, why there is a need to hide any more details.

If you're goal is to learn assembly, then you should be focusing on learning the instructions, coding procedures and building various algorithms to help refine your understanding of the low level coding. The reason most people get detoured from assembly early on is because you can't just learn assembly. From the second that you want to display the results of data movements or calculations, you immediately have to become familiar with intricate components of whatever operating system you're using. And what's worse, each operating system does things different, so that part of the code is useless when you move between various operating systems (and sometimes between different versions of the operating system).

What this guy has done is to wrap the operating system specific stuff in macros so the learner can focus on assembly without having to deal with system specific things.

I don't exactly agree with the way he's done it. To be honest, the easiest method would be to teach the students assembly, and early on in the course provide them with the details of using calls to external procedures provided by a portable language (like C).

I understand how PutStr works. But I do not understand how this GetInt Works. Wait a minute I think I guessed how this GetInt works. There is no call instruction before GetInt which means it must be a Macro.

Yep, sure is.

Let me look up there. Then, What this means

Code: [Select]
%macro  PutInt  1

It literally means "declare a macro of the name 'PutInt' that takes 1 argument".

or this

Code: [Select]
%macro  GetInt  1

%ifnidni %1,AX

        push    AX

        call    proc_GetInt

        mov     %1,AX

      pop     AX

%else

        call  proc_GetInt

%endif

%endmacro

What we have here is a wrapper to a procedure that this guy wrote. I'll try to brake it down for ya.

Code: [Select]
%macro GetInt 1
Just like in the previous, we are declaring a macro named "GetInt" that takes 1 argument.

Code: [Select]
%ifnidni %1,AX
This looks more complex than it really is... NASM uses a % followed by a number to identify which macro argument it's referencing. The %ifnidni directive compares two identifiers against each other (ignoring case) and executes the following block of code if the two identifiers are not the same.

Code: [Select]
push AX
call proc_GetInt
mov %1,AX
pop AX

If the %ifnidni line finds that the argument passed to 'GetInt' was NOT the AX register, we must preserve the value of AX, call the procedure 'proc_GetInt' which returns with the integer in AX, store that integer in the memory location or register that was passed as the parameter to 'GetInt', and finally restore the AX register in case the code that called the macro had something valuable in AX.

Code: [Select]
%else
call  proc_GetInt
%endif

This part is an alternate compilation. If the argument to 'GetInt' actually was the AX register, then we don't have to do anything except call the procedure 'proc_GetInt', and since it returns the integer in AX, you're register is already updated.

Code: [Select]
%endmacro
This line specifies that we are done declaring our 'GetInt' macro.

That's all I want to know. I have a very bad habit. I want to code everything without any io.o . I mean when I say that I can code in assembly, then I should really be able to do that. After 10 years, I do not wish to seek help of a io.o to do simplest thing. It hurts the programmer in me.

You should get out of that habit because it's a very unrealistic goal. There are very few chances in a programmers life where he can do just "pure assembly". Usually that's when you're writing framework code that'll be used by others who will deal with the system specific issues. If you code on a computer, you're going to use other peoples code, you should get used too it. Think about it, say you stop using io.o, you'll still be using the operating systems API. If you get away from the operating systems API, then you're still using the BIOS API. It's an almost never-ending cycle which only prevents you from getting any real work done.

In fact, about the only way you can write code that isn't backed by someone else's API is if you break out Verilog/VHDL and design yourself a custom CPU then get a company to print you an ASIC and code exclusively for that system. That'd be a waste of time if you ask me..

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help Needed
« Reply #19 on: June 11, 2012, 02:02:51 AM »
Quote
That's all I want to know. I have a very bad habit. I want to code everything without any io.o . I mean when I say that I can code in assembly, then I should really be able to do that. After 10 years, I do not wish to seek help of a io.o to do simplest thing. It hurts the programmer in me.

Yeah... so what's the bad habit? :)

"%1", in this context, means the first parameter passed to the macro (%2 would be the second parameter, etc.). So he IS passing parameters (to the macro, not to "proc_getInt") in registers. I guess a variable would work, too, but you'd have to provide the '[]'s. "GetInt [my_number]" would(?) work, "GetInt my_number" would not. There's a pretty good(?) section on macros in the Nasm Manual. I like Nasm, but the macro syntax is uglier than a bulldog's hind end (IMO).

I didn't make any comment on your number to string program because I thought it was pretty good. One thing that could perhaps be improved, if you want to use it as a subroutine, is to pass the buffer - a "place to put it" - as a parameter rather than hard-coding it as "output". Maybe allow the number to be someplace besides eax - although you'll want it in eax for the "div" eventually. I'll look at it again to see if I can find any nits to pick, but basically, "Good job!"

Best,
Frank

P.S. I see Bryant disagrees with me on the "bad habit". No surprise, a lot of people disagree with me on that issue. If Guarav had told me in a personal message that he hopes to learn to write an OS eventually (which he did), would that change your opinion on "always have to use someone else's API"?

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: Help Needed
« Reply #20 on: June 11, 2012, 06:16:36 AM »
If Guarav had told me in a personal message that he hopes to learn to write an OS eventually (which he did), would that change your opinion on "always have to use someone else's API"?

Your rehashing of what Bryant said is taken out of a context that was about focusing on learning assembly language. In shorter words: straw man :P

However, if you want to throw operating system development into the mix, then that means you'll have to accept a broadening of API to include any software accessible interface; whether that is a source-level API, ABI of the PC BIOS, or anything else which essentially exposes functionality in a "black box" (inputs and outputs) manner.

With respect to the above, Bryant already touched upon things that reinforces his premise, e.g. BIOS. Want to guess what word the last letter of the acronym ACPI represents? The list goes on, so I would agree that "always" (even as you put it) is still quite a sound assertion.

To step back a bit and refocus on the learning assembly language part, I would suggest using whatever you can to minimize worrying about I/O (the not-so-simplest things) so that you can focus on assembly language principles. Sometimes that means reading up on API documentation for a particular I/O system/library so you can observe your code in action.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Help Needed
« Reply #21 on: June 11, 2012, 01:33:48 PM »
P.S. I see Bryant disagrees with me on the "bad habit". No surprise, a lot of people disagree with me on that issue. If Guarav had told me in a personal message that he hopes to learn to write an OS eventually (which he did), would that change your opinion on "always have to use someone else's API"?

Not totally. Like I mentioned above:

Quote
I don't exactly agree with the way he's done it. To be honest, the easiest method would be to teach the students assembly, and early on in the course provide them with the details of using calls to external procedures provided by a portable language (like C).

This method would separate the user from system dependent issues as much as possible while still allowing them a method to view the results of their low level code. All without the worry of a possible system change crippling the courseware.

About Bryant Keller
bkeller@about.me

Offline grvtiwari

  • Jr. Member
  • *
  • Posts: 12
Re: Help Needed
« Reply #22 on: June 12, 2012, 04:13:28 AM »
Well, I agree to some of the points of everyone. For Bryant Keller sir, What if I understand myself a better, outstanding programmer just because I want to stand out of crowd. Today, with this system independent education technique, don't you see we all preparing a generation which won't know about read and write system call (the true core of assembly is being low level). I think with this, we will all lost low level knowledge. I am not a great student or a great philosopher either, I am just a student who is curious, very curious. I am in favour of low level system dependent thing. Everything should be simple but not simplest. Just because it is difficult, so it should be avoided, should not be done. I think low level knowledge is what makes a developer different and yes, a world-class programmer.

Keith Kanios Sir, I am again just a beginner, I want to grasp all the knowledge till the level of BIOS. It is only thing that would be available to me while trying to develop my OS. I was trying to learn Assembly from last 3 years. I belong to India, not so resource rich country. I had to download e-books. Everything book I tried, presented my a different syntax, a different macro file, a different assembler, a different OS. I finally decided to get over with it. I was quite acquainted with instruction because they do not change over any book. I decided to learn the few basic things from internet and through practice so as to not to get lost in any of sea of diff assemblers. I am making progress and believe me, I want to share all I know and I will.

Finally, Frank Kotler Sir, I do not why but I do share a kind of special bonding with you. It feels good to be interacting with a professional assembler developer, a developer who developed the software I use for assembling. You can count me as the one who would never leave your side. :) I am like that only. Just to let you know, I want to be like you, filled with all sort of knowledge and fledged with the capability to answer any question. I want to be coder. In my views, all ASM coders are true coder. I mean look at the IDEs today, many of us do not even know how a thing actually works. Before starting to learn ASM, I used to think I knew C language, now I am over with this misconception. Learning never stops, and I wish, it never does for me.

Sorry, for my bad English. Its not my native language. It has been on my mind since I made my first post.
Sorry, If I was rude anywhere, any time.

Thanks.

Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 429
  • Country: us
Re: Help Needed
« Reply #23 on: June 12, 2012, 03:39:01 PM »
Sir, I am again just a beginner

All levels of experience are welcome here.

...trying to develop my OS.

That is a very big topic for a beginner to tackle.  If you are going to persue that then, as a suggestion, get the source code for FreeDOS ( or Linux if you think you can handle that level of complexity ) and try to understand how the code causes the hardware to behave.  Good luck to you.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help Needed
« Reply #24 on: June 13, 2012, 06:31:23 PM »
See? I told ya a lot of people disagree with me! :)

To clarify a couple of things... I am by no means a "professional assembler developer" - strictly a "dabbler". While it is true that I've got a (very!) little code in Nasm, I'm not a good C coder and prefer to leave it to others. I think of myself as more of an "advocate" than a "developer". Where it says "hero", "experienced beginner" would be more accurate! If you want to "be like me", try to be "like me, only not so lazy" - you'll get farther!

To get back more nearly on topic... "io.o" and GetInt/PutInt generally, "hides away" two things. One is the interface to the OS. We can't do much about that. The other is the number<->text conversion(s). That should be pretty "portable" (as long as we're using ascii) and I don't see why we shouldn't drag it out into the daylight and poke at it. How does it work? How else could it be done? Is there a "best" way?

Keith and Bryant both mention the importance of the "interface". Learning to use one as a beginner, and then to provide one. So what's a good "interface" to your "number to string"? Passing parameters in registers is easy in asm. Passing parameters on the stack would allow you to call it from C as well as asm. I would have said that a "regular C calling convention" would be best... but I see that for 64-bit code they've changed it back to passing parameters in registers... 32-bit code is fast becoming obsolete, so I dunno...

Just to refresh my memory, here's the last code you posted... with some comments marked with -->...

Code: [Select]
;Program to convert number to string
;Arc-PC
;7 June 2012

SECTION .data

    msg    db    'hey! I am there always', 10
    len     equ    $-msg
   
    msg2    db    10
    len2    equ    $-msg2
   
    msg3    db    0
   

SECTION .bss

    output    resb    20
;--> output_size equ $ - output ?

SECTION .text

    global _start
   
    _start:

                        ;for 32 bit divison, Processor assumes dividend to be of 64 bits, upper 32 in EDX, lower 32 in EAX
                        ;Divisor is supposed to be provided explitly, like div ebx -> divide EDX EAX by EBX
                        ;Quotient is stored in EAX and Remainder in EDX
                       
   
    mov eax, 6250                ;A number to be changed
    mov ebx, 10                ;To be divided by 10
    mov ecx, 0
   ;--> xor ecx, ecx is shorter, and I don't think it's any slower

    loopend:
        xor edx, edx            ;Xoring EDX as it would contain the remainder, if not flushed, would screw the divison
        div ebx                ;Divide it
       
        add edx, '0'            ;Making it a Char
        push edx            ;Pushing Remainder on Stack
        inc ecx                ;Incrementing ECX
       
        cmp eax, ebx            ;CHeck whether quotient gets zero
        jl end
       
        jmp loopend            ;looping the loopend
;--> perhaps "jae loopend" would replace "jl" and "jmp"
    end:
        add eax, '0'            ;Final quotient is still waiting to be pushed, make it a char
        push eax            ;Push it on the stack
        inc ecx                ;Incrementing the ECX
        mov esi, output            ;Store the output adress
       
    combine:
        pop eax                ;Store the content
        mov [esi], eax            ;Move it to array
;--> "mov [esi], al"?  you don't really want all four bytes of eax
;--> doesn't do any harm, 'cause you overwrite the unwanted bytes, but...
        inc esi                ;Increment it
        loop combine            ;loop till ECX hold it
       
    exit:
        mov byte[esi], 10        ;Setting up the Line Feed
        mov eax, 4            ;Setting up the Write Call
        mov ebx, 1            ;Setting up stdout
        mov ecx, output            ;Taking the addrss of output
        mov edx, 10            ;Wont be used I think. Linefeed would be used.
;--> no, it'll print all ten bytes! esi - ecx should give you the actual length

        int 80h                ;Print it.
       
        mov eax, 1            ;Setting up the EXIT Ccall
        mov ebx, 0            ;Setting up the return status to OS
        int 80h                ;Yo ! Kernel do it.

TightCoderEx has some thoughts here:

http://forum.nasm.us/index.php?topic=1410.0

Best,
Frank


Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Help Needed
« Reply #25 on: June 13, 2012, 10:57:03 PM »
Well, I agree to some of the points of everyone. For Bryant Keller sir, What if I understand myself a better, outstanding programmer just because I want to stand out of crowd. Today, with this system independent education technique, don't you see we all preparing a generation which won't know about read and write system call (the true core of assembly is being low level). I think with this, we will all lost low level knowledge. I am not a great student or a great philosopher either, I am just a student who is curious, very curious. I am in favour of low level system dependent thing. Everything should be simple but not simplest. Just because it is difficult, so it should be avoided, should not be done. I think low level knowledge is what makes a developer different and yes, a world-class programmer.

The reason for the platform dependency is for the classroom. When you have a room full of (200-300) students that you're trying to teach concepts of introductory level assembly, and some of the students own Windows, others have Linux, and others have Mac OSX. How are all these students going to validate their homework if their home computer won't run the examples they are building.

I'm all in favor of low level programming, truth is I don't really see a difference in the abstraction of those macros and the abstraction of those system calls. You talk about OS development with Keith, but those system calls aren't going to be there for you when you do OS development. That being the case, learning system calls is as useless learning these macros.

About Bryant Keller
bkeller@about.me