What does .string do in assembly?
In an inline asm call in c, I wrote
.string \"Hello World\"
1) Can somebody give me an overview of how .string works?
2) Somehow that value gets saved in %esi. Why?
3) How can I append a return carriage on the end? \n doesn't work
.string is an assembler directive in GAS similar to .long, .int, or .byte. All it does is create and initialize memory for you to use in your program. The .string directive will automatically null-terminate the string with [\0] for you. In this case, the assembler is allocating space for 14 characters in 14 contiguous bytes of memory. If you were to look at the memory, you would see this:
["][H][e][l][l][o][ ][W][o][r][l][d]["][\0]
Except in hexadecimal rather than characters. I'm not sure how or why %esi points to the string (it's either an assembler setting I'm not familiar with or has been set that way on a line of code you're not showing us). What it means is that %esi "points" to the first byte of the string - in this case the first ["]. You can use the %esi register to loop through the bytes using an offset (%esi + 5 would be [o]) or by incrementing the register itself.
To add a newline you might want to try \x0D\x0A instead of \n.
It just emits a sequence of characters into the appropriate code/data section. See this and this (they use .ascii, though).
Show us the code.
Try \\n or \12 or \xa.
Related
First I tried opening a file with fopen function and print content of the file using fprint function but it was just printing a bunch of symbols to the terminal.
After a while I realized that it does not take pointer to a stream as argument and above mentioned behaviour was expected. It was printing the actual pointer value. putc or puts function also does not seem to take a pointer to the file I/O stream as an argument.
My best guess right now is I have to access the buffer fopen function created somehow! But I have no idea how or if it is possible. To sum it all up I am absolutely stuck right now.
The ultimate goal here is to get input from STDIN and/or a file do some processing on the text(eg: lowercase to uppercase) and output the result to STDOUT and/or a file. I figured If I am able to get the answer to above mentioned problem then It should help with the ultimate goal maybe.
PS: Let me know If the question can be improved in any way. Thank you.
Maybe the following code will help to get a better understanding of what I am trying to say.
.section .data
o_rdonly:
.ascii "r"
content:
.ascii "Content of the file: %d\n" #This is how I figured what those random symbols were.
.section .bss
.lcomm buffer, 10
.section .text
.globl _start
_start:
movl %esp, %ebp
pushl $o_rdonly
pushl 8(%ebp)
call fopen
##Print the content of the file?##
#pushl %eax #
#call printf #It just prints the actual address of the File I/O pointer.
pushl $0
call exit
You need to first read from the file using fread or fgets or some other function and then write what you read to standard output. There is no shortcut to directly print the contents of one file.
I wrote this code in emu8086 and it goes well in the emulator but when I'm trying to compile it with NASM it's throwing me up the error: "operation size not specified", help someone?
add bx,[3565]
sub bx,0xcc
mov [bx],0CCh
NASM can't figure out what you meant by a line like mov [bx],0CCh. Clearly,
this sets something to 0CCh. But do you want to have bx pointing to a single byte
, short, long, ...? This will manifest itself as the fairly self-explanatory
error: operation size not specified in NASM. You could avoid the error specifying the type, as shown below:
SECTION .text
global start
start:
add bx,[3565]
sub bx,0xcc
mov byte [bx],0CCh
That'd assemble it ok... of course, don't try to run it as it is, it'll produce EXCEPTION_ACCESS_VIOLATION. Just open it with a debugger and you'll understand why.
Is there a way to emulate %defstr in NASM versions earlier than 2.03, preferably 0.99.06? More particularly, I want this macro to work:
%macro name 1
%defstr __namestr__ %1
%1: db __namestr__, 0
%endmacro
so that name hello would be equivalent to hello: db 'hello', 0. It already works in NASM 2.03 and later. I need it in a portable NASM include file, and requiring the user to upgrade NASM is not an option.
This doesn't work, it emits a literal %1 (2 bytes) + NUL.
%macro name 1
%1: db '%1', 0
%endif
NASM 0.99.06 .. NASM 2.02 documentation says that a workaround can be created using a multi-line macro (for converting tokens to a string literal), but it doesn't specify how. The full excerpt:
The `%!<env>' directive makes it possible to read the value of an
environment variable at assembly time. This could, for example, be
used to store the contents of an environment variable into a string,
which could be used at some other point in your code.
For example, suppose that you have an environment variable `FOO',
and you want the contents of `FOO' to be embedded in your program.
You could do that as follows:
%define FOO %!FOO
%define quote '
tmpstr db quote FOO quote
At the time of writing, this will generate an "unterminated string"
warning at the time of defining "quote", and it will add a space
before and after the string that is read in. I was unable to find a
simple workaround (although a workaround can be created using a
multi-line macro), so I believe that you will need to either learn
how to create more complex macros, or allow for the extra spaces if
you make use of this feature in that way.
The preprocessor macro %defstr is “smart” enough and escapes, for instance, any occurrence of string delimiter characters.
Therefore it’s different from a %define simply surrounding the argument with quotes.
However, in your specific case, since the first and only parameter to the name macro must also be suitable label, you do not have to worry about problematic characters.
Taking the excerpt from the documentation as inspiration and after having verified that %+ was already documented in 0.98.x, you can write something like:
%define quote '
%macro name 1
%1: db quote %+%1%+ quote, 0
%endmacro
I did only check this with NASM version 2.15.05, so no guarantee that this indeed works with 0.99.06.
Super noob here. I'm doing a "hello world" type program in LC-3 assembly language and I simply don't know how to print more than one string to the console. I need 4 strings on separate lines that are my class, name, project and goodbye. Right now all I can seem to print in the class.
.ORIG x3000
LOOP LEA R0, CLASS
LD R1, NAME
LD R2, PROJECT
LD R3, GOODBYE
PUTS
HALT
CLASS .STRINGZ "CS101\n"
NAME .STRINGZ "JOHN\n"
...
.END
How would I get the other 3 to print? Thanks!
The Z in .STRINGZ means zero terminated. That is you have declared separate strings. If you want to print them all, you need to invoke PUTS multiple times. Alternatively, make it a single string with embedded newlines. Then you can print the whole thing in one go.
I have a dump file that I am trying to extract a very long string from. I find the thread, then find the variable and dump part of it using the following steps:
~1s
dv /v, which returns:
00000000`07a4f6e8 basicString = class _bstr_t
dt -n basicString
Command 3 truncates the string in the debugging console to just a fraction of its actual contents.
What I would like to do is find the actual length of the _bstr_t variable so that I can dump its contents out to a file with a command like the following:
.writemem c:\debugging\output\string.txt 07a4f6e8 L<StringByteLength>
So my question is how can I determine what I should put in for StringByteLength?
Your .writemem line is pretty close to what you need already.
First, you'll need the correct address of the string in memory. 07a4f6e8 is the address of the _bstr_t, so writing memory at that address won't do any good.
_bstr_t is a pretty complicated type, but ultimately it holds a BSTR member called m_wstr.
We can store its address in a register like so:
r? #$t0 = ##c++(basicString.m_Data->m_wstr)
As Igor Tandetnik's comment says, the length of a BSTR can be found in the 4 bytes preceding it.
Let's put that into a register as well:
r? #$t1 = *(DWORD*)(((BYTE*)#$t0)-4)
And now, you can writemem using those registers.
.writemem c:\debugging\output\string.txt #$t0 L?#$t1