<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	>
<channel>
	<title>
	「Step to UEFI (176）memset的实现方法」的评论	</title>
	<atom:link href="https://www.lab-z.com/stumemset/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.lab-z.com/stumemset/</link>
	<description></description>
	<lastBuildDate>Tue, 14 Jan 2020 00:50:48 +0000</lastBuildDate>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>
		评论者：ziv2013		</title>
		<link>https://www.lab-z.com/stumemset/#comment-82155</link>

		<dc:creator><![CDATA[ziv2013]]></dc:creator>
		<pubDate>Tue, 14 Jan 2020 00:50:48 +0000</pubDate>
		<guid isPermaLink="false">http://www.lab-z.com/?p=6283#comment-82155</guid>

					<description><![CDATA[回复给 &lt;a href=&quot;https://www.lab-z.com/stumemset/#comment-82046&quot;&gt;ghost_dd&lt;/a&gt;。

你是想获得当前系统内存分配情况？ 参考  https://www.lab-z.com/revmem/]]></description>
			<content:encoded><![CDATA[<p>回复给 <a href="https://www.lab-z.com/stumemset/#comment-82046">ghost_dd</a>。</p>
<p>你是想获得当前系统内存分配情况？ 参考  <a href="https://www.lab-z.com/revmem/" rel="ugc">https://www.lab-z.com/revmem/</a></p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		评论者：ghost_dd		</title>
		<link>https://www.lab-z.com/stumemset/#comment-82046</link>

		<dc:creator><![CDATA[ghost_dd]]></dc:creator>
		<pubDate>Mon, 13 Jan 2020 09:30:54 +0000</pubDate>
		<guid isPermaLink="false">http://www.lab-z.com/?p=6283#comment-82046</guid>

					<description><![CDATA[博主，你好，我想请教下有没有什么方法可以在UEFI下获取空闲内存呢]]></description>
			<content:encoded><![CDATA[<p>博主，你好，我想请教下有没有什么方法可以在UEFI下获取空闲内存呢</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		评论者：ziv2013		</title>
		<link>https://www.lab-z.com/stumemset/#comment-61293</link>

		<dc:creator><![CDATA[ziv2013]]></dc:creator>
		<pubDate>Mon, 17 Jun 2019 06:11:43 +0000</pubDate>
		<guid isPermaLink="false">http://www.lab-z.com/?p=6283#comment-61293</guid>

					<description><![CDATA[回复给 &lt;a href=&quot;https://www.lab-z.com/stumemset/#comment-61237&quot;&gt;UeThi5ne&lt;/a&gt;。

我直接用的 Wordpress 的高亮功能，没哟难过 MarkDown.]]></description>
			<content:encoded><![CDATA[<p>回复给 <a href="https://www.lab-z.com/stumemset/#comment-61237">UeThi5ne</a>。</p>
<p>我直接用的 WordPress 的高亮功能，没哟难过 MarkDown.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		评论者：De8eeg9e		</title>
		<link>https://www.lab-z.com/stumemset/#comment-61242</link>

		<dc:creator><![CDATA[De8eeg9e]]></dc:creator>
		<pubDate>Fri, 14 Jun 2019 16:32:03 +0000</pubDate>
		<guid isPermaLink="false">http://www.lab-z.com/?p=6283#comment-61242</guid>

					<description><![CDATA[仔细想了下，你可能并不是想提示编译器不优化，而是提示编译器编译时不把手工代码优化成库函数调用，或者更一般的，不引入库函数调用。类似 gcc 的 -fno-tree-loop-distribute-patterns：https://stackoverflow.com/a/33818680/1190191

msvc 好像没有类似的选项。此外 msvc 是 C++ 编译器，只是可以编译 C，但对标准的支持不理想：https://stackoverflow.com/a/48615212/1190191

不调用库函数，gcc 也能优化循环。看上去那个手动用 8 bytes 的优化是不需要的（甚至我不知道这样做是不是可能干扰编译器优化）。]]></description>
			<content:encoded><![CDATA[<p>仔细想了下，你可能并不是想提示编译器不优化，而是提示编译器编译时不把手工代码优化成库函数调用，或者更一般的，不引入库函数调用。类似 gcc 的 -fno-tree-loop-distribute-patterns：https://stackoverflow.com/a/33818680/1190191</p>
<p>msvc 好像没有类似的选项。此外 msvc 是 C++ 编译器，只是可以编译 C，但对标准的支持不理想：https://stackoverflow.com/a/48615212/1190191</p>
<p>不调用库函数，gcc 也能优化循环。看上去那个手动用 8 bytes 的优化是不需要的（甚至我不知道这样做是不是可能干扰编译器优化）。</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		评论者：laiWei8b		</title>
		<link>https://www.lab-z.com/stumemset/#comment-61238</link>

		<dc:creator><![CDATA[laiWei8b]]></dc:creator>
		<pubDate>Fri, 14 Jun 2019 09:08:15 +0000</pubDate>
		<guid isPermaLink="false">http://www.lab-z.com/?p=6283#comment-61238</guid>

					<description><![CDATA[回复给 &lt;a href=&quot;https://www.lab-z.com/stumemset/#comment-61236&quot;&gt;Ku2Ithee&lt;/a&gt;。

另外建议尽量参考 C 标准（比如 C89, C99, C11），不要依赖于编译器的行为，因为编译器一换或者升级就会发生变化，但符合标准规定的合格编译器是不会和标准冲突，尤其是开优化的时候，很可能 undefined behavior 会导致出乎意料的结果。]]></description>
			<content:encoded><![CDATA[<p>回复给 <a href="https://www.lab-z.com/stumemset/#comment-61236">Ku2Ithee</a>。</p>
<p>另外建议尽量参考 C 标准（比如 C89, C99, C11），不要依赖于编译器的行为，因为编译器一换或者升级就会发生变化，但符合标准规定的合格编译器是不会和标准冲突，尤其是开优化的时候，很可能 undefined behavior 会导致出乎意料的结果。</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		评论者：UeThi5ne		</title>
		<link>https://www.lab-z.com/stumemset/#comment-61237</link>

		<dc:creator><![CDATA[UeThi5ne]]></dc:creator>
		<pubDate>Fri, 14 Jun 2019 09:04:46 +0000</pubDate>
		<guid isPermaLink="false">http://www.lab-z.com/?p=6283#comment-61237</guid>

					<description><![CDATA[回复给 &lt;a href=&quot;https://www.lab-z.com/stumemset/#comment-61236&quot;&gt;Ku2Ithee&lt;/a&gt;。

代码嵌入混乱了。我不清楚这里怎么做是正确的。我习惯 StackOverflow 上用 markdown 的修饰符去嵌入代码。

暂时用 pastebin 吧。

C代码：https://pastebin.com/WiHWVzFZ
反汇编结果：https://pastebin.com/SrWC660z]]></description>
			<content:encoded><![CDATA[<p>回复给 <a href="https://www.lab-z.com/stumemset/#comment-61236">Ku2Ithee</a>。</p>
<p>代码嵌入混乱了。我不清楚这里怎么做是正确的。我习惯 StackOverflow 上用 markdown 的修饰符去嵌入代码。</p>
<p>暂时用 pastebin 吧。</p>
<p>C代码：https://pastebin.com/WiHWVzFZ<br />
反汇编结果：https://pastebin.com/SrWC660z</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		评论者：Ku2Ithee		</title>
		<link>https://www.lab-z.com/stumemset/#comment-61236</link>

		<dc:creator><![CDATA[Ku2Ithee]]></dc:creator>
		<pubDate>Fri, 14 Jun 2019 08:57:11 +0000</pubDate>
		<guid isPermaLink="false">http://www.lab-z.com/?p=6283#comment-61236</guid>

					<description><![CDATA[用 volatile 修饰才是正确的方法，尤其是涉及嵌入式开发的有副作用的写入。参见 https://en.cppreference.com/w/c/language/volatile
另外参见 https://stackoverflow.com/a/15618139/1190191

第一个代码，我重写了一下：
&lt;code&gt;
#include 
void *internal_memset(void *buffer, unsigned int len, uint16_t v)
{
  for (; len!=0; --len)
    ((uint16_t *)buffer)[len] = v;
  return buffer;
}
&lt;/code&gt;

在 Linux 上用 clang 开 -O2 -march=native 编译，反汇编发现它会用 SIMD 指令集 vectorization：

&lt;code&gt;
0000000000000000 :
#include 

void *internal_memset(void *buffer, unsigned int len, uint16_t v)
{
  for (; len!=0; --len)
   0:	41 57                	push   r15
   2:	41 56                	push   r14
   4:	53                   	push   rbx
   5:	85 f6                	test   esi,esi
   7:	0f 84 0f 01 00 00    	je     11c 
   d:	89 f0                	mov    eax,esi
   f:	44 8d 7e ff          	lea    r15d,[rsi-0x1]
  13:	4d 8d 47 01          	lea    r8,[r15+0x1]
  17:	49 83 f8 10          	cmp    r8,0x10
  1b:	0f 82 ef 00 00 00    	jb     110 
  21:	49 bb f0 ff ff ff 01 	movabs r11,0x1fffffff0
  28:	00 00 00 
  2b:	4d 89 c1             	mov    r9,r8
  2e:	4d 21 d9             	and    r9,r11
  31:	4d 89 c2             	mov    r10,r8
  34:	4d 21 da             	and    r10,r11
  37:	0f 84 d3 00 00 00    	je     110 
  3d:	c5 f9 6e c2          	vmovd  xmm0,edx
  41:	4d 8d 77 01          	lea    r14,[r15+0x1]
  45:	4d 21 de             	and    r14,r11
  48:	49 83 c6 f0          	add    r14,0xfffffffffffffff0
  4c:	44 89 f1             	mov    ecx,r14d
  4f:	c1 e9 04             	shr    ecx,0x4
  52:	83 c1 01             	add    ecx,0x1
  55:	31 db                	xor    ebx,ebx
  57:	f6 c1 07             	test   cl,0x7
  5a:	74 36                	je     92 
    ((uint16_t *)buffer)[len] = v;
  5c:	c4 e2 7d 79 c8       	vpbroadcastw ymm1,xmm0
  61:	48 8d 4c 47 e2       	lea    rcx,[rdi+rax*2-0x1e]
  66:	83 e6 70             	and    esi,0x70
  69:	83 c6 f0             	add    esi,0xfffffff0
  6c:	c1 ee 04             	shr    esi,0x4
  6f:	83 c6 01             	add    esi,0x1
  72:	83 e6 07             	and    esi,0x7
  75:	48 f7 de             	neg    rsi
  78:	31 db                	xor    ebx,ebx
  7a:	66 0f 1f 44 00 00    	nop    WORD PTR [rax+rax*1+0x0]
  80:	c5 fe 7f 09          	vmovdqu YMMWORD PTR [rcx],ymm1
  for (; len!=0; --len)
  84:	48 83 c3 10          	add    rbx,0x10
  88:	48 83 c1 e0          	add    rcx,0xffffffffffffffe0
  8c:	48 83 c6 01          	add    rsi,0x1
  90:	75 ee                	jne    80 
  92:	49 83 fe 70          	cmp    r14,0x70
  96:	72 65                	jb     fd 
    ((uint16_t *)buffer)[len] = v;
  98:	c4 e2 7d 79 c0       	vpbroadcastw ymm0,xmm0
  for (; len!=0; --len)
  9d:	49 83 c7 01          	add    r15,0x1
  a1:	4d 21 df             	and    r15,r11
  a4:	49 29 df             	sub    r15,rbx
  a7:	48 8d 4c 00 e2       	lea    rcx,[rax+rax*1-0x1e]
  ac:	48 01 db             	add    rbx,rbx
  af:	48 29 d9             	sub    rcx,rbx
  b2:	48 01 f9             	add    rcx,rdi
  b5:	66 66 2e 0f 1f 84 00 	data16 nop WORD PTR cs:[rax+rax*1+0x0]
  bc:	00 00 00 00 
    ((uint16_t *)buffer)[len] = v;
  c0:	c5 fe 7f 01          	vmovdqu YMMWORD PTR [rcx],ymm0
  c4:	c5 fe 7f 41 e0       	vmovdqu YMMWORD PTR [rcx-0x20],ymm0
  c9:	c5 fe 7f 41 c0       	vmovdqu YMMWORD PTR [rcx-0x40],ymm0
  ce:	c5 fe 7f 41 a0       	vmovdqu YMMWORD PTR [rcx-0x60],ymm0
  d3:	c5 fe 7f 41 80       	vmovdqu YMMWORD PTR [rcx-0x80],ymm0
  d8:	c5 fe 7f 81 60 ff ff 	vmovdqu YMMWORD PTR [rcx-0xa0],ymm0
  df:	ff 
  e0:	c5 fe 7f 81 40 ff ff 	vmovdqu YMMWORD PTR [rcx-0xc0],ymm0
  e7:	ff 
  e8:	c5 fe 7f 81 20 ff ff 	vmovdqu YMMWORD PTR [rcx-0xe0],ymm0
  ef:	ff 
  for (; len!=0; --len)
  f0:	48 81 c1 00 ff ff ff 	add    rcx,0xffffffffffffff00
  f7:	49 83 c7 80          	add    r15,0xffffffffffffff80
  fb:	75 c3                	jne    c0 
  fd:	4d 39 d0             	cmp    r8,r10
 100:	74 1a                	je     11c 
 102:	4c 29 c8             	sub    rax,r9
 105:	66 66 2e 0f 1f 84 00 	data16 nop WORD PTR cs:[rax+rax*1+0x0]
 10c:	00 00 00 00 
    ((uint16_t *)buffer)[len] = v;
 110:	66 89 14 47          	mov    WORD PTR [rdi+rax*2],dx
  for (; len!=0; --len)
 114:	48 83 c0 ff          	add    rax,0xffffffffffffffff
 118:	85 c0                	test   eax,eax
 11a:	75 f4                	jne    110 
  return buffer;
 11c:	48 89 f8             	mov    rax,rdi
 11f:	5b                   	pop    rbx
 120:	41 5e                	pop    r14
 122:	41 5f                	pop    r15
 124:	c5 f8 77             	vzeroupper 
 127:	c3                   	ret    
&lt;/code&gt;]]></description>
			<content:encoded><![CDATA[<p>用 volatile 修饰才是正确的方法，尤其是涉及嵌入式开发的有副作用的写入。参见 <a href="https://en.cppreference.com/w/c/language/volatile" rel="nofollow ugc">https://en.cppreference.com/w/c/language/volatile</a><br />
另外参见 <a href="https://stackoverflow.com/a/15618139/1190191" rel="nofollow ugc">https://stackoverflow.com/a/15618139/1190191</a></p>
<p>第一个代码，我重写了一下：<br />
<code><br />
#include<br />
void *internal_memset(void *buffer, unsigned int len, uint16_t v)<br />
{<br />
  for (; len!=0; --len)<br />
    ((uint16_t *)buffer)[len] = v;<br />
  return buffer;<br />
}<br />
</code></p>
<p>在 Linux 上用 clang 开 -O2 -march=native 编译，反汇编发现它会用 SIMD 指令集 vectorization：</p>
<p><code><br />
0000000000000000 :<br />
#include </p>
<p>void *internal_memset(void *buffer, unsigned int len, uint16_t v)<br />
{<br />
  for (; len!=0; --len)<br />
   0:	41 57                	push   r15<br />
   2:	41 56                	push   r14<br />
   4:	53                   	push   rbx<br />
   5:	85 f6                	test   esi,esi<br />
   7:	0f 84 0f 01 00 00    	je     11c<br />
   d:	89 f0                	mov    eax,esi<br />
   f:	44 8d 7e ff          	lea    r15d,[rsi-0x1]<br />
  13:	4d 8d 47 01          	lea    r8,[r15+0x1]<br />
  17:	49 83 f8 10          	cmp    r8,0x10<br />
  1b:	0f 82 ef 00 00 00    	jb     110<br />
  21:	49 bb f0 ff ff ff 01 	movabs r11,0x1fffffff0<br />
  28:	00 00 00<br />
  2b:	4d 89 c1             	mov    r9,r8<br />
  2e:	4d 21 d9             	and    r9,r11<br />
  31:	4d 89 c2             	mov    r10,r8<br />
  34:	4d 21 da             	and    r10,r11<br />
  37:	0f 84 d3 00 00 00    	je     110<br />
  3d:	c5 f9 6e c2          	vmovd  xmm0,edx<br />
  41:	4d 8d 77 01          	lea    r14,[r15+0x1]<br />
  45:	4d 21 de             	and    r14,r11<br />
  48:	49 83 c6 f0          	add    r14,0xfffffffffffffff0<br />
  4c:	44 89 f1             	mov    ecx,r14d<br />
  4f:	c1 e9 04             	shr    ecx,0x4<br />
  52:	83 c1 01             	add    ecx,0x1<br />
  55:	31 db                	xor    ebx,ebx<br />
  57:	f6 c1 07             	test   cl,0x7<br />
  5a:	74 36                	je     92<br />
    ((uint16_t *)buffer)[len] = v;<br />
  5c:	c4 e2 7d 79 c8       	vpbroadcastw ymm1,xmm0<br />
  61:	48 8d 4c 47 e2       	lea    rcx,[rdi+rax*2-0x1e]<br />
  66:	83 e6 70             	and    esi,0x70<br />
  69:	83 c6 f0             	add    esi,0xfffffff0<br />
  6c:	c1 ee 04             	shr    esi,0x4<br />
  6f:	83 c6 01             	add    esi,0x1<br />
  72:	83 e6 07             	and    esi,0x7<br />
  75:	48 f7 de             	neg    rsi<br />
  78:	31 db                	xor    ebx,ebx<br />
  7a:	66 0f 1f 44 00 00    	nop    WORD PTR [rax+rax*1+0x0]<br />
  80:	c5 fe 7f 09          	vmovdqu YMMWORD PTR [rcx],ymm1<br />
  for (; len!=0; --len)<br />
  84:	48 83 c3 10          	add    rbx,0x10<br />
  88:	48 83 c1 e0          	add    rcx,0xffffffffffffffe0<br />
  8c:	48 83 c6 01          	add    rsi,0x1<br />
  90:	75 ee                	jne    80<br />
  92:	49 83 fe 70          	cmp    r14,0x70<br />
  96:	72 65                	jb     fd<br />
    ((uint16_t *)buffer)[len] = v;<br />
  98:	c4 e2 7d 79 c0       	vpbroadcastw ymm0,xmm0<br />
  for (; len!=0; --len)<br />
  9d:	49 83 c7 01          	add    r15,0x1<br />
  a1:	4d 21 df             	and    r15,r11<br />
  a4:	49 29 df             	sub    r15,rbx<br />
  a7:	48 8d 4c 00 e2       	lea    rcx,[rax+rax*1-0x1e]<br />
  ac:	48 01 db             	add    rbx,rbx<br />
  af:	48 29 d9             	sub    rcx,rbx<br />
  b2:	48 01 f9             	add    rcx,rdi<br />
  b5:	66 66 2e 0f 1f 84 00 	data16 nop WORD PTR cs:[rax+rax*1+0x0]<br />
  bc:	00 00 00 00<br />
    ((uint16_t *)buffer)[len] = v;<br />
  c0:	c5 fe 7f 01          	vmovdqu YMMWORD PTR [rcx],ymm0<br />
  c4:	c5 fe 7f 41 e0       	vmovdqu YMMWORD PTR [rcx-0x20],ymm0<br />
  c9:	c5 fe 7f 41 c0       	vmovdqu YMMWORD PTR [rcx-0x40],ymm0<br />
  ce:	c5 fe 7f 41 a0       	vmovdqu YMMWORD PTR [rcx-0x60],ymm0<br />
  d3:	c5 fe 7f 41 80       	vmovdqu YMMWORD PTR [rcx-0x80],ymm0<br />
  d8:	c5 fe 7f 81 60 ff ff 	vmovdqu YMMWORD PTR [rcx-0xa0],ymm0<br />
  df:	ff<br />
  e0:	c5 fe 7f 81 40 ff ff 	vmovdqu YMMWORD PTR [rcx-0xc0],ymm0<br />
  e7:	ff<br />
  e8:	c5 fe 7f 81 20 ff ff 	vmovdqu YMMWORD PTR [rcx-0xe0],ymm0<br />
  ef:	ff<br />
  for (; len!=0; --len)<br />
  f0:	48 81 c1 00 ff ff ff 	add    rcx,0xffffffffffffff00<br />
  f7:	49 83 c7 80          	add    r15,0xffffffffffffff80<br />
  fb:	75 c3                	jne    c0<br />
  fd:	4d 39 d0             	cmp    r8,r10<br />
 100:	74 1a                	je     11c<br />
 102:	4c 29 c8             	sub    rax,r9<br />
 105:	66 66 2e 0f 1f 84 00 	data16 nop WORD PTR cs:[rax+rax*1+0x0]<br />
 10c:	00 00 00 00<br />
    ((uint16_t *)buffer)[len] = v;<br />
 110:	66 89 14 47          	mov    WORD PTR [rdi+rax*2],dx<br />
  for (; len!=0; --len)<br />
 114:	48 83 c0 ff          	add    rax,0xffffffffffffffff<br />
 118:	85 c0                	test   eax,eax<br />
 11a:	75 f4                	jne    110<br />
  return buffer;<br />
 11c:	48 89 f8             	mov    rax,rdi<br />
 11f:	5b                   	pop    rbx<br />
 120:	41 5e                	pop    r14<br />
 122:	41 5f                	pop    r15<br />
 124:	c5 f8 77             	vzeroupper<br />
 127:	c3                   	ret<br />
</code></p>
]]></content:encoded>
		
			</item>
	</channel>
</rss>
