string to char array?

via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jun 6 03:12:52 PDT 2015


On Friday, 5 June 2015 at 19:19:23 UTC, Kyoji Klyden wrote:
> On Friday, 5 June 2015 at 18:30:53 UTC, Kagamin wrote:
>> Well, reading assembler is good enough:
>>
>> void f(int[] a)
>> {
>>  a[0]=0;
>>  a[1]=1;
>>  a[2]=2;
>> }
>>
>> Here pointer is passed in rsi register and length - in rdi:
>>
>> void f(int[]):
>> 	push	rax
>> 	test	rdi, rdi
>> 	je	.LBB0_4
>> 	mov	dword ptr [rsi], 0
>> 	cmp	rdi, 1
>> 	jbe	.LBB0_5
>> 	mov	dword ptr [rsi + 4], 1
>> 	cmp	rdi, 2
>> 	jbe	.LBB0_6
>> 	mov	dword ptr [rsi + 8], 2
>> 	pop	rax
>> 	ret
>> .LBB0_4:
>> 	mov	edi, 55
>> 	mov	esi, .L.str
>> 	mov	edx, 5
>> 	call	_d_arraybounds
>> .LBB0_5:
>> 	mov	edi, 55
>> 	mov	esi, .L.str
>> 	mov	edx, 6
>> 	call	_d_arraybounds
>> .LBB0_6:
>> 	mov	edi, 55
>> 	mov	esi, .L.str
>> 	mov	edx, 7
>> 	call	_d_arraybounds
>>
>> You play with assembler generated for D code at 
>> http://ldc.acomirei.ru/
>
> Never said I was good at asm but I'll give it a shot...
>
> So push rax to the top of the memory stack, test if rdi == rdi 
> since yes jump to.LBB0_4, in LBB0_4 move the value 55 into edi, 
> then move .L.str (whatever that is) into esi, then 5 into edx, 
> then call _d_arraybounds (something from Druntime maybe?) then 
> LBB0_4 has nothing left so go back, move the value 0 into a 
> 32-bit pointer(to rsi register), if rdi == 1 jump to LBB0_5 
> (pretty much the same as LBB0_4), then move 1 into the pointer 
> (which points to rsi[+ 4 bytes cuz it's an int]), so on and so 
> forth until we pop rax from the memory stack and return.
>
> How did I do? :P (hopefully at least B grade)

Almost correct :-) The part of "has nothing left, so go back" is 
wrong. The call to _d_arraybounds doesn't return, because it 
throws an Error.

>
> I'm not really sure what .L.str or _d_arraybounds is, but I'm 
> guessing it's the D runtime?

Yes, inside the `f` function, the compiler cannot know the length 
of the array during compilation. To keep you from accidentally 
accessing invalid memory (e.g. if the array has only two 
elements, but you're trying to access the third), it 
automatically inserts a check, and calls that runtime helper 
function to throw an Error if the check fails. .L.str is most 
likely the address of the error message or filename, and 55 is 
its length. The 5/6/7 values are the respective line numbers. You 
can disable this behaviour by compiling with `dmd 
-boundscheck=off`.

>
> Also in the mov parts, is that moving 1 into the pointer or 
> into the rsi register? And is rsi + 4, still in rsi, or does it 
> move to a different register?

It stores the `1` into the memory pointed to by `rsi`, or `rsi+4` 
etc. This is what the brackets [...] mean. Because it's an array 
of ints, and ints are 4 bytes in size, [rsi] is the first 
element, [rsi+4] the second, and [rsi+8] the third. `rsi+4` is 
just a temporary value that is only used during the store, it's 
not saved into a (named) register. This is a peculiarity of the 
x86 processors; they allow quite complex address calculations for 
memory accesses.


More information about the Digitalmars-d-learn mailing list