Take This Life

Take This Life (https://www.takethislife.com/)
-   Science and Technology (https://www.takethislife.com/science-technology/)
-   -   Assembly programming (https://www.takethislife.com/science-technology/assembly-programming-287836/)

Ehisdi 07-03-18 03:04 AM

Assembly programming
 
Now this won't be concise, nor will it be platform independent, but it may help my brain pick up some things that I've forgotten, or just can't concentrate on...So this may take quite a while to pull that information out of my noggin.


System: Slackware 14.0 and 14.2
Bits: 64
Assembler: Nasm and Yasm
Assembly flavour: Intel syntax.

General purpose registers on a 64 bit system...


AH : AL = {AX} =>{00:00}

EAX = 00:00:00:00

RAX = 00:00:00:00:00:00:00:00

If memory serves, BH, BL, CH, CL, and not sure about DH, DL exist, but I haven't had the need to use those since the old days. So they are a tad unnecessary.

But I do use the following.

BX < EBX < RBX (Using the less than sign to show that they are smaller/larger than the others. And that they follow the same rules as the AX < EAX < RAX.

CX < ECX < RCX
DX < EDX < RDX

R# (I don't remember these off hand, and I need to get ready for bed, so I'll come back to this when I can).

SP < ESP < RSP (Why would someone use the lesser? I don't know. I could, but I really have no need to do so).

BP < EBP < RBP (Again, not really necessary, but can be used if one wants...)

There's a rule about the nSP and nBP registers, don't forget them, else your program will crash like there's no tomorrow.

The other registers, MMX, YMMX or whatever registers, I haven't used these as of yet. It's on my todo list, but I'm getting older, so I may never touch them. Eh, c'est la vie.

The FLAGS register is a special register, which is used by several instructions, primarily flow control.

Lets take a simple C if statement and translate it into assembly...(Also, lets see if the code tags work).

Code:

if (a == 0)
  b = 15;
else
  b = 5

MOV AX, 5      ; There's a reason I'm doing these next two lines.
MOV CX, 3
TEST BX, BX    ; We're saying that the variable 'a' is in BX.
JNZ if_done      ; If BX does not equal 0, or 'a' does not equal zero, then we're done.
MUL CX          ; Else multiply by 3.
if_done:          ; We finished the if statement.

; ------------------------------------------------------------------------
; Here's another way this same if statement can be written.

MOV AX, 5
TEST BX, BX
JNZ if_done
OR AX, 10
if_done:

; ------------------------------------------------------------------------
; And lastly, a slightly quicker one, but reliant on AX being empty.

TEST BX, BX
JNZ if_done
MOV AX, 15
if_done:
OR AX, 5

If you note, I wrote the assembly backwards. Instead of doing "if (a==0) b=15; else b=5;" I did "if (a!=0) b=5; else b=15;". The reason for that is, when writing assembly you try to simplify everything a lot. So sometimes, what you write in c, c++, whatever language won't be how you'd write it in assembly.

I think I may have messed something up there...But I'm finally tired, and it's only 2am...Which is good enough for me...So I'll come back to this some other time...Hopefully...
Oh, if anyone has any questions, go for it. I'd love to talk with someone, and it'd sure help to get my brain to function, heh.

EmpatheticThoughts 07-03-18 03:20 AM

If you don't mind me asking, how long have you been programming?

Ehisdi 07-03-18 11:56 AM

Quote:

Originally Posted by EmpatheticThoughts (Post 2908064)
If you don't mind me asking, how long have you been programming?

I think 99 is when I first got into it quite a bit, as I wasn't allowed to do much nor had enough documentation to learn the Atari XE or this small keyboard only computer my mom had back in the late 80's.

For c and assembly, though, that was much later. Around 2008 - 2010, right before my brain decided I didn't need to think coherently anymore, heh.

If I can immerse myself into the code, though, it gets really really easy to do regardless which language I choose. The hard part is getting started.

Still would like to finish at least this one bit of code in assembly. I've been wanting to write my own big number library that uses only the set of integers. I did have the multiplication, subtraction, addition, and few other initializing routines written up, but I realized late in the development that I had two major flaws in it. If I could just get my darn mind to concentrate on it, I could make a few changes without having to rewrite everything. Kind of aggravating, heh.

Honestly, though, I have to put programming on the side for the moment. Since I've been out of work for so long, I'm needing to find something that my aching body will let me do to make at least some money, and programming (which I love the most that my body can do on a regular basis) just isn't a viable option here. So, arts and crafts are my best bet (And my creativity has been shot to all hell from the poor marriage and pains I've been in since 2000).

EmpatheticThoughts 07-03-18 07:12 PM

Quote:

If I can immerse myself into the code, though, it gets really really easy to do regardless which language I choose. The hard part is getting started.
This is good to hear. I consider myself to be a relatively lazy person (mostly because of social anxiety) but I have a degree in math. How long do you think it would take me to be able to pick it up?

Quote:

Honestly, though, I have to put programming on the side for the moment. Since I've been out of work for so long, I'm needing to find something that my aching body will let me do to make at least some money, and programming (which I love the most that my body can do on a regular basis) just isn't a viable option here. So, arts and crafts are my best bet (And my creativity has been shot to all hell from the poor marriage and pains I've been in since 2000).
Where is programming not a viable option??

Ehisdi 07-03-18 10:32 PM

Quote:

Originally Posted by EmpatheticThoughts (Post 2908104)
This is good to hear. I consider myself to be a relatively lazy person (mostly because of social anxiety) but I have a degree in math. How long do you think it would take me to be able to pick it up?

Depends on a couple of factors. If you plan on aiming higher than a hobby, opensource, or tinkering around, then I'd suggest looking into C++ as that would help with java and C# which would be of far greater benefit. Now, if you're interested in digging down deep into coding, or hobby, opensource, and/or tinkering, then c and assembly would be beneficial.

As for picking up, that's a little tricky, and each person learns in a different way. For example, most people can pick up the use of "*" in c as both multiplication and pointer data type with ease, for me I didn't get used to the pointer types until I learned assembly. Also, depending on what I'm writing, I'm far more comfortable in assembly than I am in C, but for legibility, C is much much higher on that list.

Code:


\\  C code here.    This is easier to read.
a = 0;
for(x=1;x<30;x++) a=a+x;

; Assembly  This is easier to understand.

MOV RCX, 29      ; Let RCX = 29, and since 29 < 30, this is the maximum.
XOR AX, AX        ; This sets AX = 0
Begin_Loop:        ; The start of the loop
ADD AX, CX        ; This is basically a = a + x, or AX = AX + CX.
loop Begin_Loop  ; This is basically, CX = CX - 1 then go to Begin_Loop.

\\ C code of the assembly, but written more approximately with the assembly.
\\ It does exactly the same thing, it's just not as legible.
for(x=29;x>0;x--) a = a + x;

Anyhoo, as long as you can read, you can pick up any programming language. There are a lot of materials on line, and there are a great many forums that would help with learning assembly. There's even a few debuggers out there that would help a lot with that as well. As for a math degree helping in programming, that's not really that important. I say that, but, and this but is a biggy, it comes in handy for dealing with algorithms and speeding up code. This is one area that maybe delving into some minor assembly would be highly beneficial. You have to really really REEEEAAAAAAAAALLLLY think about how you might want to handle a routine.

Here's my bigmul routine that I wrote in assembly.

Quote:

Where is programming not a viable option??
Western Kansas. Now if I could care enough, I could always write a game, I found the allegro library which I could use to write games, and I do enjoy 2D RTS type games, but two things keep me from doing so, 1. Pain and stress. I'm in such an amount of pain and so stressed that my creativity is just gone. 2. Nobody, and I mean nobody would allow me the time necessary to learn the necessary elements to get it going. I'm the cook, person who is supposed to take care of everyone and everything at any given moment, and if I try, I get in trouble for it. That's been my life since I was young. It's stupid to be a mathematician, oceanographer, lexicographer, botanist. You're too retarded to go to college. You're too lazy to make anything of yourself. You don't get to do what you want, you have to hurt like hell working for a horrible boss for the rest of your life. These are the kinds of things that were fed into my head ever since I was little, and lo and behold, I made them true...Sheesh...And to make matters worse, I married a woman who believed the same...So yeah, my mind is kind of messed up from years of trying to keep my mentality from going insane, then as soon as I met my wife in 2000, I began working at a job that just tore my body to shreds...Heh, I'm a mess.

EmpatheticThoughts 07-04-18 01:18 AM

Quote:

Originally Posted by Ehisdi (Post 2908178)
1. Pain and stress. I'm in such an amount of pain and so stressed that my creativity is just gone. 2. Nobody, and I mean nobody would allow me the time necessary to learn the necessary elements to get it going. I'm the cook, person who is supposed to take care of everyone and everything at any given moment, and if I try, I get in trouble for it. That's been my life since I was young. It's stupid to be a mathematician, oceanographer, lexicographer, botanist. You're too retarded to go to college. You're too lazy to make anything of yourself. You don't get to do what you want, you have to hurt like hell working for a horrible boss for the rest of your life. These are the kinds of things that were fed into my head ever since I was little, and lo and behold, I made them true...Sheesh...And to make matters worse, I married a woman who believed the same...So yeah, my mind is kind of messed up from years of trying to keep my mentality from going insane, then as soon as I met my wife in 2000, I began working at a job that just tore my body to shreds...Heh, I'm a mess.

You're not mess. Thank you for talking to me. I can relate to the putdowns. I struggle with feeling good about myself from somethings that happened in my childhood. Hi, I'm ET, I also have self-sabotaged :wave:

You don't need to use a lot of logic for programming? I know algorithms use logic.

Ehisdi 07-04-18 02:31 AM

Quote:

Originally Posted by EmpatheticThoughts (Post 2908192)
You're not mess. Thank you for talking to me. I can relate to the putdowns. I struggle with feeling good about myself from somethings that happened in my childhood. Hi, I'm ET, I also have self-sabotaged :wave:

Yay, heh.

Quote:

You don't need to use a lot of logic for programming? I know algorithms use logic.
Well, well disciplined logic verses disorganized logic. Just imagine a drunk trying to explain something as simple as how to drive verses when he's sober. The logic is still there, but the ability to explain it efficiently is not. (If that makes sense, :eek:).

Heh, It's one of the few things that causes us low level programmers to get antsy whenever we talk with high level programmers. I know a kid who writes C# and java programs and he doesn't quite grasp boolean operands, which in low level programming are something of a necessity to speed up code, and algorithms quite often.

EmpatheticThoughts 07-04-18 03:30 AM

You're making me excited to start pick this up again! I understood your explanation of disciplined knowledge vs disorganized logic. You're saying basic programming is more intuitive and straightforward.

Ehisdi 07-04-18 03:39 AM

You could say that, but as the old adage goes, "what's normal for the spider is chaos for the fly", or in me and my wife's positions, "What's normal for the programmer is pointless to the current Dr. Who episode", heh.

Ehisdi 07-15-18 02:42 AM

itob (Integer to binary string)
 
Eureka, as I holler naked through the streets of Syracuse.

Talked with the wife and my mind seems to be coming back to me, well at least my calculative part of my mind. Conversing, on the other hand, nope. That's still beyond my mental capacity.

Anyway, I wrote a small little routine in assembly and thought I'd share it and give some insight into what I did, and why I did it (having to relearn things, so there may be some stuff that would make these things better).

Code:

;
;  itob "Integer to Binary string"

;  c calling: itob(char *destination, int num)
;
;  Assembly: itob  RDI, RSI
;  Registers used: RDI, RSI, RCX
;
section .text
  global itob

itob:
    MOV      RCX, 32      ; Begin our loop for an integer.

    MOV BYTE [RDI], 0x30  ; Set the first character to the 0 character.
itob_find_c:
    SHL      ESI, 1      ; Shift until we find our first 1.
    JC      itob_begin  ; Then begin
  LOOP      itob_find_c  ; Continue searching
    INC      RDI
    JMP      itob_finish  ; Else there are no 1's then exit with 0.
itob_begin:
    ADC BYTE [RDI], 0      ; Add the 1
    INC      RDI          ; Move to next character writing position.
    MOV BYTE [RDI], 0x30  ; Set to the 0 character.
    SHL      ESI , 1      ; Else check for the next character.
  LOOP      itob_begin  ; Continue at itob_begin.

itob_finish:
    MOV BYTE [RDI], 0x0        ; Null terminate the string.
    RET

What happens? And why?

When the routine is called, the first thing that is done is RCX is set for the LOOP instruction. (Note: I didn't have to use RCX, I could have written ECX as the upper 32bits would have automagically been set to 0. Meh, force of habit).

The LOOP instruction decrements the RCX value, and I just read that one should refrain from using the LOOP instruction, O_o, however, in this code, it seems to be the best suited, at least at the moment. (If I can keep thinking on this, I definitely will be able to remember things and possibly find a better method than this).

Ok, so lets go through what is being done...
  1. RCX = 32, set this to the length of an integer (at least on my AMD system).
  2. Set the first character to '0'.
    • Since '0' is 0x30, and '1' is 0x31 in ascii characters. All we have to do is 0x30+1 to get '1'.
    • Also, by initializing it to '0', if 0 is passed to the routine, it will automagically have '0' set for the integer 0.
  3. SHL ESI, 1 : Shift ESI to the left (0010 becomes 0100)
  4. JC itob_begin : If the bit removed was a 1, then lets begin creating our string.
  5. LOOP itob_find_c : Return to itob_find_c until the first 1 is found.
  6. Increment RDI to the next character to be written (this is where the NULL terminating character will be written to, as there were no 1's to be found).
  7. JMP itob_finish : We're done, there's nothing more to do.
  8. ADC BYTE [RDI], 0 : If a 1 was found, then add it to our '0' character, else just add 0 to '0'.
    (I think this is where I could simplify this code down by quite a bit, but I'm unsure at the moment).
  9. INC RDI : Move to the next character write position. If at end of string, then this is where we add the NULL terminating character.
  10. MOV BYTE [RDI], 0x30 : Write the '0' character.
    Why would I use both MOV and ADC? Because there may already be data in [RDI], to which ADC would merely ADD the carry with 0x30 "with" the data that already exists in [RDI] So the MOV statement clears that.
  11. SHL ESI, 1 : Shift ESI to the left.
  12. LOOP itob_begin : Return to itob_begin til RCX = 0.
  13. MOV BYTE [RDI], 0x0 : Set the last character to the NULL terminating character.
  14. RET : return out of this routine.

Ok, I really need to try to get to sleep, but I hope some nerd out there will enjoy this. Again, if by perchance anyone has any questions, ask away. I really really could use the practice of explaining things to others, heh.

Ehisdi 07-15-18 11:15 PM

Hoo boy, I'm in so much pain, and I doubt I'll be able to explain this bit of code all that well, but here goes.

Code:

;  #1                                      #2                                        #3
 itobf:                                  itobf:                                    itobf:                     
    DEC        RDX                          AND          DL , 1111b                    AND          DL , 1111b
    ADD        RDI , RDX                                                                                       
    INC        RDX                          MOV          CL ,  DL                      MOV          CL ,  DL 
    SHL        RDX ,  2                    SHL          CL ,  2                      SHL          CL ,  2 
    ADD        RDI , RDX                    ROR        RSI ,  CL                      ROR        RSI ,  CL     
    MOV BYTE  [RDI],  0                itobf_begin:                              itobf_begin:             
    DEC        RDI                          XOR        EAX , EAX                      XOR        EAX , EAX 
 itobf_begin:                            itobf_genword:                                MOV          CL ,  4
    XOR          AL ,  AL                    SHL        RSI ,  1                  itobf_genword:           
    SHR        RSI ,  1                    ADC          AL , 0x30                    SHL        RSI ,  1
    ADC          AL , 0x30                  ROR        EAX ,  8                      ADC          AL , 0x30
    MOV BYTE  [RDI],  AL                                                              ROR        EAX ,  8
    DEC        RDI                          SHL        RSI ,  1                                                     
    DEC          DL                          ADC          AL , 0x30                    DEC          CL                         
  TEST          DL ,  DL                    ROR        EAX ,  8                    TEST          CL ,  CL 
    JZ        itobf_ret                                                              JNZ        itobf_genword
  TEST          DL ,  3                    SHL        RSI ,  1                      DEC          DL           
    JZ        itobf_write_delem            ADC          AL , 0x30                                                   
    JMP        itobf_begin                  ROR        EAX ,  8                      MOV DWORD  [RDI],  AX   
 itobf_write_delem:                                                                    ADD        RDI ,  4
    MOV BYTE  [RDI], ':'                    SHL        RSI ,  1                                                   
    DEC        RDI                          ADC          AL , 0x30                    TEST          DL ,  DL   
    JMP        itobf_begin                  ROR        EAX ,  8                      JZ          itobf_ret   
                                                                                     
 itobf_ret:                                  DEC          DL                            MOV BYTE  [RDI], ':'
    RET                                                                                INC        RDI
                                            MOV DWORD  [RDI], EAX                      JMP        itobf_begin
                                            ADD        RDI ,  4                  itobf_ret:
                                                                                        MOV BYTE  [RDI],  0
                                            TEST          DL ,  DL                      RET                     
                                              JZ          itobf_ret                 
                                                                                     
                                            MOV BYTE  [RDI], ':'                                         
                                            INC        RDI                                         
                                            JMP        itobf_begin                                         
                                          itobf_ret:                                         
                                            MOV BYTE  [RDI],  0                                         
                                            RET

I haven't tested #3, so I don't know if it works or not, it should, but meh, it wasn't meant to work, just a modification of #2 to show it with less code.

As for which one I'm sticking with, I'm sticking with #2 as it's quicker than the rest, and it's a good one for showing how writing multiple lines which do the same thing is far superior to using loops. (I won't explain how, as I'm just too exhausted from this pain, but trust me, :thumbsup:)

#1 took me most of today to write, and #2 only took me a few minutes, #3, about a minute or two.

What this code does, is it translates an integer into a binary representation along with a string delimiter, so the following would take place for a number 34979.

Code:

itobf(str, 34979, 4); str = "1000:1000:1010:0011"
itobf(str, 34979, 3); str = "1000:1010:0011"
itobf(str, 34979, 2); str = "1010:0011"
itobf(str, 34979, 1); str = "0011"

(Woops, just noticed the "AND DL, 1111b" is wrong. It should be "AND DL, 111b", and I should "DEC DL" to ensure that only up to 4 bytes are read.
Code:

DEC DL    ; Ensure that if 8 is passed, it becomes 7, which equals 111b
AND DL , 111b    ; Make sure DL is not greater than 7.
INC  DL              ; Increment DL to ensure all whole four bytes can be read.

Yeah, in way too much pain. I can't concentrate beyond this. Well, hope someone likes it.

EmpatheticThoughts 07-17-18 09:50 PM

I like it lol
And I hope you feel better soon! :hug:

Ehisdi 07-18-18 11:08 PM

Oh-kay! I revamped my itob routine, it's a bit longer than the old one, but it's still pretty quick.

Code:


; itob( char * source, int A, int len)

itob:
    MOV          AX , 0x30          ; Setup first character.
  TEST          DL ,  DL          ; Is length used?
    JZ        itob_skip_init_dl
    MOV          CL ,  DL          ; Setup length.
    ROR        ESI ,  CL          ; Rotate that bastard.
    ROL        ESI ,    1
    JMP        itob_l              ; Go ahead and start reading.

itob_skip_init_dl:                  ; We're using the entire integer.
    MOV          CL ,  33          ; We're going to read the whole integer.
itob_find_first_c:                  ; Find first carry bit.
    DEC          CL
    JZ        itob_ret            ; If 0, then write '0' and call it good.
    ROL        ESI ,    1          ; Find our carry.
    JNC        itob_find_first_c

itob_l:                            ; Now we can create that bloody string.
    ADC          AL ,    0          ; Create our character.
    DEC          CL
    JZ        itob_ret            ; Length found, get outta here.
    MOV BYTE  [RDI],  AL          ; Write our current character.
    INC        RDI                ; Prepare for next character.
    MOV          AL , 0x30          ; Reset our new character
    ROL        ESI ,    1          ; Get next bit.
    JMP        itob_l              ; Redo all this crap.
itob_ret:
    MOV WORD  [RDI],  AX
    RET

This one will restrict the size of the integer read by the variable len, and pad with zeroes. If len = 0, then the entire integer is read and it is not padded with zeroes.

Basically,
Code:

itob(str, 37, 3); str = "101"
itob(str, 37, 15); str = "000000000100101"
itob(str, 37, 0); str = "100101"

What really blows about this one, I kind of forgot to do the error checking, :confused:. Meh, the pain caused me too much duress and I really really had a hell of a time thinking on this.

Ehisdi 07-20-18 05:13 AM

Still having massive troubles with sleeping, so I decided to revisit my big integer library that I've been trying to re-write in assembly...

So, in order to utilize the stack space, which would allow me to keep a lot of the old code I've already written, as well as make a lot of the work so so soooo much simpler, I've decided to use the following lines of code...

Code:

  PUSH RBP            Save RBP
  MOV  RBP, RSP      Save RSP
  MOV  RSP, bigint    Setup bigint to RSP
;  And I have to re-read how the stack space is setup, because I may have to do the following
;  SHL  RCX , 3        Multiply the length of bigint by 8.
;  ADD  RSP , RCX  Add that number to RSP so the stack space starts at the "end".
;                            Of course, I could just ADD, but I may PUSH and POP, too.
;                            Haven't made up my mind yet...O_o.  Hmm?
; ... Do stuff
;
  MOV RSP, RBP    Restore RSP
  POP  RBP            Restore RBP

And what I've decided to do for dealing with all the data, is generate a "linked list".

Code:

a = new_bigint();  // This would create a new bigint, and append it to
                  // the linked list, and 'a' would point to this new number.

Now comes the interesting hypothesis, if realloc is called and the space created moves to a new location, two things may happen with the old memory location, 1. A temporary qword stores the "new" location, and the old qword will read that location to copy data over, or, OR, 2. Backup the pointer to a register/stack/whatever and "trust" that some other program doesn't overwrite that space while the data copying is taking place. (If I can get more sleep and think on this more logically, I may ask about this in one of the programming forums I used to frequent).

Lastly, by utilizing a linked list for storing all the big integers, then the "deconstructor" (free) routine could be written without having to rewrite it every single time.

Code:


init_bigint();  // Initialize the linked list, and a temporary number.

a = new_bigint();
// Several lines of code later.
b = new_bigint();
// Even more lines of code later.
c = new_bigint();

free_bigint();  // Free all big integers created...
// This would make the code so much easier to read, as well as it would definitely be a lot cleaner.

End of brain fart...Very very sleepy...Very very sore...

Ehisdi 07-26-18 03:08 AM

Mental note to self: The following code is perfectly fine...(I asked someone in another forum and they concurred).

Code:

MOV  reg , [reg]
AND  reg , [reg]
; etc


Ehisdi 08-03-18 12:30 AM

Holy halibuts I'm having such trouble concentrating...

Anyhoo, I got the first macros at least finished.

Code:

;  Assembly macros



;backupTo From  #1, #2...
;
;  Push/Pop #2+ To/From stack, and move stack to #1.
;
;  Keep order for quick copy/paste within vim.

%macro backupTo 1-*
    %rotate 1
    %rep %0-1
        PUSH  %1
    %rotate 1
    %endrep
        MOV  %1, RSP
%endmacro


%macro resetFrom 1-*
        MOV RSP, %1
    %rep %0-1
    %rotate -1
        POP %1
    %endrep
%endmacro
   

; mpush mpop    Multi Push and Pop
;
;    Keep order for quick copy/paste in vim.


%macro mpush 1-*
    %rep %0
        PUSH %1
    %rotate 1
    %endrep
%endmacro

%macro mpop 1-*
    %rep %0
    %rotate -1
        POP %1
    %endrep
%endmacro

This way, I can use the following code (and quick copy/paste within vim).

Code:

    backupTo RBP, reg1, reg2, reg3, ...
    ;  ... Do stuff here
    resetFrom RBP, reg1, reg2, reg3, ...

; And

    mpush reg1, reg2, ...
    ; ... Do stuff here
    mpop  reg1, reg2, ...


Ehisdi 10-06-18 10:20 PM

Alrighty! Was able to use some of my mind so I wrote a few things down, and made some hella mods to my Makefile and binary/hex routines.

Makefile
Note: Need to research .PHONY in a Makefile.
Code:

ASMSRC=$(wildcard *.asm)
ASMOBJ=$(patsubst %.asm,%.o,$(ASMSRC))

ASSDBG= -g dwarf2

ASS=yasm
ASSFLAGS= -f elf64 $(ASSDBG) $(USEWITHC) -D HEX_DELEM="'-'" -D _USE_BIN_SUFFIX_


CSRC=conv.c
PRGNAM=convtest

CC=gcc
CFLAGS= -g -Wall

all:        $(ASMOBJ) ccode


%.o: %.asm
        $(ASS) $(ASSFLAGS) $< -o [email protected]


ccode:
        $(CC) $(CFLAGS) $(CSRC) $(ASMOBJ) -o $(PRGNAM)

clean:
        rm $(ASMOBJ) $(PRGNAM)

itobs.asm

I think I need to redo my Makefile to reflect the changes to each routine, as a common use Makefile section might prove to be too much...O_o.

Code:

;  Defines
;
;  BINARY_DELEM  Every fourth character in binary
;                  representation will contain this character.
;  _USE_BIN_PREFIX_  use 0b as a prefix.
;  _USE_BIN_SUFFIX_  use b as a suffix.

%ifdef BINARY_DELEM
%ifnstr BINARY_DELEM
%define BINARY_DELEM ':'
%endif
%endif


section .text

    global itobs

;
;
;  itobs( src ,  C , len )
;  itobs( RDI , RSI , RDX )
;
;  len == 0, return a single bit.
;
;  Registers used:  CL
;


itobs:
  AND          DL ,  111111b              ; Ensure <= 64 bits are read.
  INC          DL
  MOV          CL ,  DL                  ; Only CL can be used by ROR.
  ROR        RSI ,  CL

%ifdef _USE_BIN_PREFIX_
  MOV          AX ,  '0b'
  MOV WORD  [RDI],    AX
  ADD        RDI ,    2
%endif

itobs_loop:
  MOV BYTE  [RDI], 0x30                  ; Write '0' to string.
  SHL        RSI ,    1                  ; test bit.
  ADC BYTE  [RDI],    0                  ; Add 1 if it's a 1 to the '0'.

  INC        RDI                          ; Next char write.

  DEC          DL                          ; Subtract 1 from DL.

%ifdef BINARY_DELEM
    JZ        itobs_exit                  ; Get outta here if DL == 0
 
  TEST          DL ,  11b                  ; Is DL == 0 ( MOD 4 )?
  JNZ        itobs_loop                  ; If not, continue reading number.
  MOV BYTE  [RDI],  BINARY_DELEM        ; Add our delemeter string.
  INC        RDI
  JMP        itobs_loop                  ; Continue reading number.
%else

  JNZ        itobs_loop
%endif
   

itobs_exit:

%ifdef _USE_BIN_SUFFIX_
    MOV        AX ,  0x0062
    MOV WORD [RDI],    AX
%else
    MOV BYTE [RDI],    0                ; Write null char.
%endif
    RET

itoxs.asm

Code:

;  Defines
;
;  HEX_DELEM  Change the string delimeter.
;
;  _USE_HEX_PREFIX_ Use 0x for the hexadecimal prefix.
;  _USE_HEX_SUFFIX_ Use h for the hex suffix.
;  _NO_HEX_DELEM_  Do not delimate the hexadecimal string.

%ifdef HEX_DELEM
%ifnstr HEX_DELEM
%define HEX_DELEM ':'
%endif
%endif

section .text
    global itoxs


;  itoxs( char *src, number, length )
;
;  itoxs( RDI, RSI, RDX )


itoxs:
    AND          DL ,      1111b      ; < 64 bits.
    MOV          CL ,      DL          ; CL can only be used with RO#
    SHL          CL ,          2
    ROR        RSI ,      CL

%ifdef _USE_HEX_PREFIX_
    MOV          AX ,      '0x'
    MOV WORD  [RDI],      AX
    ADD        RDI ,        2
%endif

itoxs_loop:
    MOV          AL ,      SIL
    AND          AL ,      1111b

    CMP          AL ,      10
    JL          itoxs_less
    ADD          AL ,        7

itoxs_less:
    ADD          AL ,    0x30
    MOV BYTE  [RDI],      AL
    INC        RDI


    ROL        RSI ,        4

    DEC          DL

%ifdef HEX_DELEM
    JS          itoxs_exit

  TEST          DL ,        1
    JZ          itoxs_loop
    MOV BYTE  [RDI],      HEX_DELEM
    INC        RDI
    JMP          itoxs_loop
%else

    JNS          itoxs_loop
%endif

itoxs_exit:

%ifdef _USE_HEX_SUFFIX_
    MOV          AX,      0x0068
    MOV WORD  [RDI],      AX
%else
    MOV BYTE  [RDI],        0
%endif

    RET

All in all, regardless of the overuse of macros, it's still quite fascinating none-the-less. Plus, it really helps to understand the preprosessor better. I likey very much. I just need more experience with Make files, though.

Ehisdi 10-14-18 10:53 PM

Alrighty! After a lot of "dumb" time, I finally had enough brain umph to research the XMM registers. They're useful for double/single precision numbers, but integers, they're crap. So...I really have no use for them, at least now. So that answers that question, and I can stop fretting about the "what ifs".

Ehisdi 11-11-18 01:47 AM

And or xor not shl shr ror rol
 
The instructions I'm going to write about are the following, AND, OR, XOR, NOT, SHL, SHR, ROR, ROL.

Prerequisite:

As most know, computers only see 1's and 0's. A good way to think of this, is "on" and "off", or "set" and "not set".

So any number, character, be it a byte: 0000:0000 (Hexadecimal 0x:00), a word: 0000:0000:0000:0000 (Hexadecimal 0x:00:00), an dword 0x:00:00:00:00, and a quadword 0x:00:00:00:00:00:00:00:00, is represented in this fashion.

1 = 0000:0001
2 = 0000:0010
4 = 0000:0100
So on and so forth.

SHL, SHR
The best way to explain this, is division by 2 and multiple of 2.

Code:

MOV AL ,  1  ; AL = 1, or 0000:0001
SHL  AL ,  1  ; AL = 2, or 0000:0010
SHR  AL ,  1  ; AL = 1, or 0000:0001

; Note AL is an 8 bit register.

As should be apparent, the 1 moves SHL (Left) and SHR (Right). ROR and ROL behave in the same way, however, with the following differences.

Code:

MOV AL ,  1  ; AL = 0000:0001 = 1
SHR AL ,  1  ; AL = 0000:0000 = 0

MOV AL ,  1  ; AL = 0000:0001 = 1
ROR AL ,  1  ; AL = 1000:0000 = 128

Note: In the SHR instruction the 1 was SHifted Right (And there's nowhere for the 1 to shift right to).
In the ROR instruction the 1 was ROtated Right or ROlled Right (So the 1 was ROlled to the other side of the 8 bit register).

The rest of the instructions (I hope I can continue with a decent explanation of as my mind is starting to falter), should be apparent with the following code.

Code:

MOV  AL ,  0b101    ; AL = 5 = 0000:0101
AND  AL ,  0b11      ; AL = 1 = 0000:0001
;  AND means that all 1's are kept, so
;  0101
;& 0011    Note: Only the final 1's line up. The rest do not.
;--------
;  0001
MOV AL ,  0b101    ; AL = 5
 OR AL ,  0b11        ; AL = 7 = 0000:0111
; Or means "if" a 1 exists in any place, any operand, it stays put.
;
MOV AL , 0b101 ; AL = 5
XOR AL , 0b011 ; AL = 6
; XOR basically is like saying "opposing bits shall always be 1, and all like bits shall be 0".
; 1 xor 1 = 0
; 0 xor 0 = 0
; 1 xor 0 = 0 xor 1 = 1

MOV AL , 5  ; AL = 0000:0101
NOT AL        ; AL = 1111:1010
; Basically, NOT reverses the bits.  If 1, then 0, or if "on" then "off".

All of this may seem confusing, but in programming, this is a very necessary part of that experience. Many algorithms can be broken down to using just a few if not all of these instructions. Even high level programming can benefit with their use.

(My brain has faltered, and can't concentrate any more. If anyone has any questions, it'd sure help with focusing my thoughts, but there's too few of us oddballs out there who'd like to know more, :rolleyes:)


All times are GMT -5. The time now is 05:54 PM.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2021, vBulletin Solutions, Inc.
Shoutbox provided by vBShout v6.2.1 (Lite) - vBulletin Mods & Addons Copyright © 2021 DragonByte Technologies Ltd.
vBulletin Security provided by vBSecurity v2.2.2 (Pro) - vBulletin Mods & Addons Copyright © 2021 DragonByte Technologies Ltd.


Content Relevant URLs by vBSEO 3.3.2