Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Storing String (Texts) :: ASM

kuphrynkuphryn Member Posts: 266
Hi.

How do you store a string of characters in a variable or register?

-----
...
.DATA

// This line works.
MyString DB 'testing $'

// This line does not work.
// MASM error is: error A2084: constant value too large

MyString DB ?

.CODE

mov MyString, 'testing 1 2 3'
-----

I would like to know how to move a string of characters to a variable and/or a register at any point of the code instead of just in .DATA.

Thanks,
Kuphryn
«1

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : Hi.
    :
    : How do you store a string of characters in a variable or register?
    :
    : -----
    : ...
    : .DATA
    :
    : // This line works.
    : MyString DB 'testing $'
    :
    : // This line does not work.
    : // MASM error is: error A2084: constant value too large
    :
    : MyString DB ?
    :
    : .CODE
    :
    : mov MyString, 'testing 1 2 3'
    : -----
    :
    : I would like to know how to move a string of characters to a variable and/or a register at any point of the code instead of just in .DATA.
    :
    : Thanks,
    : Kuphryn
    :
    [blue]Obviously, whole string cannot fit into a register, so usually you keep in the register string address - the offset to the first symbol in that string:

    .DATA
    MyString Db 'Text... bla-bla!$' ; 16 chars + '$'

    .CODE
    Mov bx, offset [MyString]

    Now, to actually move/hold string you need buffers with the sufficient room to hold your data.

    .DATA
    buf1 Db 8 dup (0) ; 'MyString' will NOT fit in here
    buf2 Db 24 dup (0) ; 'MyString' will fit in here

    To actually move strings around you need to use MOVSx instruction:

    Push ds ; Make sure DS=ES, because your 'buf2' in the same segment
    Pop es

    Mov si, offset [MyString] ; Source
    Mov di, offset [buf2] ; Destination
    Cld ; Clear Direction: (SI,DI go forward)
    Mov cx, 17 ; The whole 'MyString' room
    Rep movsb ; Repeat Move byte until CX is zero (17 times)

    [/blue]
  • kuphrynkuphryn Member Posts: 266
    Nice!!! Thanks.

    You presented a algorithm for copy a string. I will definitely put it to good use.

    I am most familiar with C++ and thus am used to declaring a string object to a character array or a pointer to a character array.

    -----
    char *pText = "testing 1 2 3";

    // Or

    string sText = "testing 1 2 3";
    -----

    I tried to apply the same technique, but ASM would not accept it.

    -----
    mov ax, 'testing...'
    -----

    In summation, I tried to not have to declare a variable in .DATA.

    Kuphryn

    Kuphryn
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : Nice!!! Thanks.
    :
    : You presented a algorithm for copy a string. I will definitely put it to good use.
    :
    : I am most familiar with C++ and thus am used to declaring a string object to a character array or a pointer to a character array.
    :
    : -----
    : char *pText = "testing 1 2 3";
    :
    : // Or
    :
    : string sText = "testing 1 2 3";
    : -----
    :
    : I tried to apply the same technique, but ASM would not accept it.
    :
    : -----
    : mov ax, 'testing...'
    : -----
    : [blue]Registers can be only addresses of strings. When you work in ASM with strings you should always keep in mind - when you say 'string' you mean 'address to a string'. Say, you need a routine to concatenate strings. You would think: "OK, here I need two strings...". Right away you replace 'strings' with 'addresses to strings'.
    [/blue]
    : In summation, I tried to not have to declare a variable in .DATA.
    [blue]What is the reason for that? You need some .DATA variables for sure. Or you try to be a dogma follower. Usually, large project managers say: "I ain't having any globals in this project!..". So, all the objects will be referenced by a bunch of pointers and the code will be slow.
    [/blue]
    :
    : Kuphryn
    :
    : Kuphryn
    :

  • kuphrynkuphryn Member Posts: 266
    hahah. Thanks.

    Do you know how we try not to declare every variable we use in C++ OOP classes? That is bad program design. In general, you only declare a variable when you need it and try to declare them as a local variable when possible. I tried to apply the same OOP design to ASM.

    Kuphryn
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : hahah. Thanks.
    :
    : Do you know how we try not to declare every variable we use in C++ OOP classes? That is bad program design. In general, you only declare a variable when you need it and try to declare them as a local variable when possible. I tried to apply the same OOP design to ASM.
    :
    : Kuphryn
    :
    [blue]Why there is a problem? Use [b]LOCAL[/b] directive:[/blue][code]
    DoIt Proc
    local dwCount:dword, i:word=VarsRoom
    enter VarsRoom, 0

    mov eax, dwCount
    mov bx, i

    push ss
    pop es
    lea di, [i] ; Take address of 'i' into ES:DI

    ALWAYS_EXIT_HERE:
    leave
    ret
    DoIt EndP
    [/code]
  • kuphrynkuphryn Member Posts: 266
    Nice! Thanks.

    In the local declaration of your code, does this line initialize i to the content of VarsRoom?

    -----
    local dwCount:dword, i:word=VarsRoom
    -----

    Kuphryn
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : Nice! Thanks.
    :
    : In the local declaration of your code, does this line initialize i to the content of VarsRoom?
    :
    : -----
    : local dwCount:dword, i:word=VarsRoom
    : -----
    :
    : Kuphryn
    :
    [blue]No. [b]VarsRoom[/b] takes a value of room for all local vars - in that case 6 bytes (word + dword). To get more locals declared use '' at the end of the line:
    [code]
    STR64 Struc
    Buf Db 64 Dup (?)
    STR64 EndS

    local var1:dword, var2:dword,
    str3:STR64, pData:dword=VarsRoom
    [/code]See, how cool! You can even use your own types in that sequence. I declared a string (or 64-byte area) of 63 symbols and terminator and used it as a local variable. In that case:

    VarsRoom = 3 x dwords + 64 bytes = 12+64 = 76 bytes
    [/blue]
  • kuphrynkuphryn Member Posts: 266
    Okay. Do you mean pData:dword=VarsRoom is required when declare LOCAL variables?

    Kuphryn
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : Okay. Do you mean pData:dword=VarsRoom is required when declare LOCAL variables?
    :
    : Kuphryn
    :
    [blue]I do not think it is requred:[/blue][code]
    MyFunc Proc
    local a:dword, b:dword
    enter 8, 0 ; Why 8? Because 8 bytes for 'a+b'

    ; ...your code here...

    leave
    ret
    MyFunc EndP
    [/code][blue]But then if you decide to add a variable, say, another DWORD - you have to fix '8' to be 12 now. It is a hassle, because, if you forgot it - trouble not easy to find - the variable will get some random values. Compiler allows '=name' at the end of LOCAL section to indicate how many bytes is in the whole LOCAL section. This way when you add something - compiler will pick it up automatically.[/blue]
  • kuphrynkuphryn Member Posts: 266
    Okay. Thanks.

    Can you write up a quick example of using the LOCAL declaring for a combination of BYTE, WORD, and DWORD?

    -----
    LOCALE Small:DB, Big:DW, Large:DD
    -----

    How will the size declaration look lock?

    Kuphryn
«1
Sign In or Register to comment.