Assembly programming - Page 2
Take This Life  

Go Back   Take This Life > The Lighter Side > Hobbies > Science and Technology

Assembly programming

This is a discussion on Assembly programming within the Science and Technology forums, part of the Hobbies category; Hoo boy, I'm in so much pain, and I doubt I'll be able to explain this bit of code all ...

join us
Reply
 
LinkBack Thread Tools
Old 07-15-18, 10:15 PM   #11
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default

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, )

#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.
Ehisdi is offline   Reply With Quote
Old 07-17-18, 08:50 PM   #12
Member
 
Join Date: Oct 2014
Posts: 624
Default

I like it lol
And I hope you feel better soon!
__________________
Be who you are and say what you feel, because in the end those who matter don't mind and those who mind don't matter. - Dr. Seuss
EmpatheticThoughts is offline   Reply With Quote
Old 07-18-18, 10:08 PM   #13
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default

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, . Meh, the pain caused me too much duress and I really really had a hell of a time thinking on this.
Ehisdi is offline   Reply With Quote
Sponsored Links
Advertisement
 
Old 07-20-18, 04:13 AM   #14
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default

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 is offline   Reply With Quote
Old 07-26-18, 02:08 AM   #15
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default

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 is offline   Reply With Quote
Old 08-02-18, 11:30 PM   #16
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default

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 is offline   Reply With Quote
Old 10-06-18, 09:20 PM   #17
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default

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 is offline   Reply With Quote
Old 10-14-18, 09:53 PM   #18
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default

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 is offline   Reply With Quote
Old 11-11-18, 12:47 AM   #19
Junior Member
 
Ehisdi's Avatar
 
Join Date: Jun 2018
Location: Kansas
Posts: 72
My Mood:
Default 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, )
Ehisdi is offline   Reply With Quote
Reply

« Vim Fanatics Unite | - »
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -5. The time now is 02:50 PM.


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

Content Relevant URLs by vBSEO 3.3.2