gcc为函数生成指令内为什么会有多处return

函数返回

如果一个函数的返回点比较多,而且函数比较长,想通过调试器知道函数从哪个位置退出就会比较麻烦。有些资料说一般编译器的所有return最终会经过同一条ret(机器指令)返回,所以只要找到该指令的位置打断点即可。这个对于没有开优化的指令可能是正确的,开启优化生成的二进制中经常可以看到一个函数内有多处ret,所以这种说法并不准确。

return语义

在对return语句的处理过程中,所有的return生成的指令的确是跳转到相同位置(return_label)。

/* Output a return with no value.  */

static void
expand_null_return_1 (void)
{
  clear_pending_stack_adjust ();
  do_pending_stack_adjust ();
  emit_jump (return_label);
}

jump redirect

try_optimize_cfg函数中,如果满足


	      /* Try to change a branch to a return to just that return.  */
	      rtx_insn *ret, *use;
	      if (single_succ_p (b)
		  && onlyjump_p (BB_END (b))
		  && bb_is_just_return (single_succ (b), &ret, &use))

则尝试修改跳转的目的地为ret指定的label,这里也就是最终的返回地址。

	  if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
			     PATTERN (ret), 0))

也就是

/* Create some permanent unique rtl objects shared between all functions.  */
void
init_emit_once (void)
{
///...
simple_return_rtx = gen_rtx_fmt_ (SIMPLE_RETURN, VOIDmode);
///...
}

中创建的SIMPLE_RETURN特殊类型表达式。如果跳转的目的是这个label,生成的汇编代码(对386系统来说)就是一条ret机器指令。

/* Return true if BB contains just a return and possibly a USE of the
   return value.  Fill in *RET and *USE with the return and use insns
   if any found, otherwise NULL.  */

static bool
bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
{
  *ret = *use = NULL;
  rtx_insn *insn;

  if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    return false;

  FOR_BB_INSNS (bb, insn)
    if (NONDEBUG_INSN_P (insn))
      {
	if (!*ret && ANY_RETURN_P (PATTERN (insn)))
	  *ret = insn;
	else if (!*ret && !*use && GET_CODE (PATTERN (insn)) == USE
	    && REG_P (XEXP (PATTERN (insn), 0))
	    && REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
	  *use = insn;
	else
	  return false;
      }

  return !!*ret;
}

/* Do simple CFG optimizations - basic block merging, simplifying of jump
   instructions etc.  Return nonzero if changes were made.  */

static bool
try_optimize_cfg (int mode)
{
///...
	  for (b = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; b
	       != EXIT_BLOCK_PTR_FOR_FN (cfun);)
	    {
///...
	      /* Try to change a branch to a return to just that return.  */
	      rtx_insn *ret, *use;
	      if (single_succ_p (b)
		  && onlyjump_p (BB_END (b))
		  && bb_is_just_return (single_succ (b), &ret, &use))
		{
		  if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
				     PATTERN (ret), 0))
		    {
		      if (use)
			emit_insn_before (copy_insn (PATTERN (use)),
					  BB_END (b));
		      if (dump_file)
			fprintf (dump_file, "Changed jump %d->%d to return.\n",
				 b->index, single_succ (b)->index);
		      redirect_edge_succ (single_succ_edge (b),
					  EXIT_BLOCK_PTR_FOR_FN (cfun));
		      single_succ_edge (b)->flags &= ~EDGE_CROSSING;
		      changed_here = true;
		    }
		}
///...
	}
///...
}

epilogue

在函数逻辑生成之后,在函数的结尾生成函数的epilogue,这个逻辑可以不同的后端自己定制。


/* Return a sequence to be used as the epilogue for the current function,
   or NULL.  */

static rtx_insn *
make_epilogue_seq (void)
{
  if (!targetm.have_epilogue ())
    return NULL;

  start_sequence ();
  emit_note (NOTE_INSN_EPILOGUE_BEG);
  rtx_insn *seq = targetm.gen_epilogue ();
  if (seq)
    emit_jump_insn (seq);

  /* Retain a map of the epilogue insns.  */
  record_insns (seq, NULL, &epilogue_insn_hash);
  set_insn_locations (seq, epilogue_location);

  seq = get_insns ();
  rtx_insn *returnjump = get_last_insn ();
  end_sequence ();

  if (JUMP_P (returnjump))
    set_return_jump_label (returnjump);

  return seq;
}

复杂epilogue

如果一些epilogue比较复杂,可能涉及到栈帧的调整,这个时候basic_block_reorder流程就有可能重新复制一份代码。在386系统下,如果开启了optimize_bb_for_speed_p,只要bb的指令长度小于16,就有可能被拷贝一份。

///@file:bb-reorder.c
/* Return true when BB can and should be copied. CODE_MAY_GROW is true
   when code size is allowed to grow by duplication.  */

static bool
copy_bb_p (const_basic_block bb, int code_may_grow)
{
  int size = 0;
  int max_size = uncond_jump_length;
  rtx_insn *insn;

  if (!bb->frequency)
    return false;
  if (EDGE_COUNT (bb->preds) < 2)
    return false;
  if (!can_duplicate_block_p (bb))
    return false;

  /* Avoid duplicating blocks which have many successors (PR/13430).  */
  if (EDGE_COUNT (bb->succs) > 8)
    return false;

  if (code_may_grow && optimize_bb_for_speed_p (bb))
    max_size *= PARAM_VALUE (PARAM_MAX_GROW_COPY_BB_INSNS);

  FOR_BB_INSNS (bb, insn)
    {
      if (INSN_P (insn))
	size += get_attr_min_length (insn);
    }

  if (size <= max_size)
    return true;

  if (dump_file)
    {
      fprintf (dump_file,
	       "Block %d can't be copied because its size = %d.\n",
	       bb->index, size);
    }

  return false;
}

机器描述

在i386.md中描述了对应的机器指令。

;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
;; instruction Athlon and K8 have.

(define_insn "simple_return_internal_long"
  [(simple_return)
   (unspec [(const_int 0)] UNSPEC_REP)]
  "reload_completed"
  "* return ix86_output_function_return (true);"
  [(set_attr "length" "2")
   (set_attr "atom_unit" "jeu")
   (set_attr "length_immediate" "0")
   (set_attr "prefix_rep" "1")
   (set_attr "modrm" "0")])

(define_insn_and_split "simple_return_pop_internal"
  [(simple_return)
   (use (match_operand:SI 0 "const_int_operand"))]
  "reload_completed"
  "%!ret\t%0"
  "&& cfun->machine->function_return_type != indirect_branch_keep"
  [(const_int 0)]
  "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
  [(set_attr "length" "3")
   (set_attr "atom_unit" "jeu")
   (set_attr "length_immediate" "2")
   (set_attr "modrm" "0")
   (set_attr "maybe_prefix_bnd" "1")])

栗子

在开启优化的版本中有多处ret指令。

tsecer@harry: cat multi.return.cpp 
int foo(int x, int y)
{
        switch (x)
        {
                case 1: return y * 1;
                case 2: return y * 2;
                case 3: return y * 3;
                case 4: return y * 4;
        }
}

tsecer@harry: gcc -O3 -S multi.return.cpp
tsecer@harry: cat multi.return.s 
        .file   "multi.return.cpp"
        .text
        .p2align 4,,15
        .globl  _Z3fooii
        .type   _Z3fooii, @function
_Z3fooii:
.LFB0:
        .cfi_startproc
        cmpl    $2, %edi
        je      .L3
        jle     .L12
        cmpl    $3, %edi
        je      .L6
        leal    0(,%rsi,4), %eax
        ret
        .p2align 4,,10
        .p2align 3
.L6:
        leal    (%rsi,%rsi,2), %eax
        ret
        .p2align 4,,10
        .p2align 3
.L12:
        movl    %esi, %eax
        ret
        .p2align 4,,10
        .p2align 3
.L3:
        leal    (%rsi,%rsi), %eax
        ret
        .cfi_endproc
.LFE0:
        .size   _Z3fooii, .-_Z3fooii
        .section        .note.GNU-stack,"",@progbits
tsecer@harry: 

bb拷贝栗子


tsecer@harry: cat bb.copy.cpp 
int foo(int x, int y)
{
    int a[20];
    extern int bar(int *);
    bar(a);
switch (x)
{
case 1: return y * 1;
case 2: return y * 2;
case 3 : return y *3;    
case 4: return y *4;
}
return x * 5;
}

tsecer@harry: gcc -O3 -S bb.copy.cpp
tsecer@harry: cat bb.copy.s 
        .file   "bb.copy.cpp"
        .text
        .p2align 4,,15
        .globl  _Z3fooii
        .type   _Z3fooii, @function
_Z3fooii:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        pushq   %rbx
        .cfi_def_cfa_offset 24
        .cfi_offset 3, -24
        movl    %edi, %ebp
        movl    %esi, %ebx
        subq    $88, %rsp
        .cfi_def_cfa_offset 112
        movq    %rsp, %rdi
        call    _Z3barPi
        cmpl    $2, %ebp
        je      .L3
        jle     .L13
        cmpl    $3, %ebp
        je      .L6
        cmpl    $4, %ebp
        leal    0(,%rbx,4), %eax
        jne     .L2
.L1:
        addq    $88, %rsp
        .cfi_remember_state
        .cfi_def_cfa_offset 24
        popq    %rbx
        .cfi_def_cfa_offset 16
        popq    %rbp
        .cfi_def_cfa_offset 8
        ret
        .p2align 4,,10
        .p2align 3
.L6:
        .cfi_restore_state
        addq    $88, %rsp
        .cfi_remember_state
        .cfi_def_cfa_offset 24
        leal    (%rbx,%rbx,2), %eax
        popq    %rbx
        .cfi_def_cfa_offset 16
        popq    %rbp
        .cfi_def_cfa_offset 8
        ret
        .p2align 4,,10
        .p2align 3
.L13:
        .cfi_restore_state
        cmpl    $1, %ebp
        movl    %ebx, %eax
        je      .L1
.L2:
        addq    $88, %rsp
        .cfi_remember_state
        .cfi_def_cfa_offset 24
        leal    0(%rbp,%rbp,4), %eax
        popq    %rbx
        .cfi_def_cfa_offset 16
        popq    %rbp
        .cfi_def_cfa_offset 8
        ret
        .p2align 4,,10
        .p2align 3
.L3:
        .cfi_restore_state
        addq    $88, %rsp
        .cfi_def_cfa_offset 24
        leal    (%rbx,%rbx), %eax
        popq    %rbx
        .cfi_def_cfa_offset 16
        popq    %rbp
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE0:
        .size   _Z3fooii, .-_Z3fooii
        .section        .note.GNU-stack,"",@progbits
tsecer@harry: 

本文转载于网络 如有侵权请联系删除

相关文章

  • Docker pull 失败,更换国内源daocloud

    配置Docker镜像站daocloudlinux配置$curl-sSLhttps://get.daocloud.io/daotools/set_mirror.sh|sh-shttp://f1361db2.m.daocloud.io复制macOS:右键点击桌面顶栏的docker图标,选择Preferences,在Daemon标签(Docker17.03之前版本为Advanced标签)下的Registrymirrors列表中加入下面的镜像地址:http://f1361db2.m.daocloud.io复制windows:在桌面右下角状态栏中右键docker图标,修改在DockerDaemon标签页中的json,把下面的地址:http://f1361db2.m.daocloud.io复制

  • 加推完成1亿元A+轮融资|腾讯SaaS加速器·学员动态

    来源| 腾讯SaaS加速器首期项目-加推腾讯SaaS加速器二期30席项目招募报名方式腾讯SaaS加速器,作为腾讯产业加速器的一个重要组成部分,旨在搭建腾讯与SaaS相关企业的桥梁,通过资本、技术、资源、商机等层面的扶持,从战略到场景落地全方位加速企业成长,助力产业转型升级。二期招募正式开始,扫描 二维码 立刻报名(或点击文末 “阅读原文”,直达报名入口)详情介绍:寻找SaaS“潜力军”,腾讯SaaS加速器二期开启招募祝贺腾讯SaaS加速器首期成员-智能CRM技术提供商“加推”完成来自仁智资本的1亿元A+轮融资 ———— /END/ ———— 腾讯SaaS加速器·产业升级实战派腾讯SaaS加速器,作为腾讯产业加速器的一个重要组成部分,旨在搭建腾讯与SaaS相关企业的桥梁,通过资本、技术、资源、商机等层面的扶持,从战略到场景落地全方位加速企业成长,助力产业转型升级。

  • Go Web编程--SecureCookie实现客户端Session管理

    在Web应用开发中Session是在用户和服务器之间进行交换的非持久化交互信息。当用户登录时,可以在用户和服务器之间生成Session,然后来回交换数据,并在用户登出时销毁Session。gorilla/sessions软件包提供了易于使用的Go语言Session实现。该软件包提供了两种不同的实现。第一个是文件系统存储,它将每个会话存储在服务器的文件系统中。另一个是Cookie存储,它使用我们上篇文章讲的SecureCookie在客户端上存储会话。同时还提供了用户自定义Session存储实现的选项,我们可以根据应用的需求自己实现Session存储。因为我们的教程是学会使用为目的就不大费周章的去实现MySQL或者Redis版本的Session存储了,我们直接使用软件包提供的Cookie实现来完成本节的Session相关内容。GoWeb编程系列的每篇文章的源代码都打了对应版本的软件包,供大家参考。公众号中回复gohttp09获取本文源代码使用Cookie存储用户Session的优缺点客户端使用Cookie管理用户Session较之在服务器进行用户的Session管理会有一些优势。客户端Se

  • python学习计划大全(从入门到放弃)

    第一阶段-语言基础(15天) python基础语法 python字符串解析 python时间和日历 python文件操作,数据处理 python界面编程 python面向对象高级语法 命名空间和作用域应用案例分析 项目:图形界面实现数据查询、python实战2048、语音对话开发、语音控制开发 第二阶段-语言高级(15天) python处理txt,csv,pdf,jsons python平台迁移linux python常用第三方库 python发送邮件 python发送短信 python高级语法 python正则表达式 python网络编程 python系统编程 pythonpyGame pythonOffice办公自动化 python数据库开发 jpython简介 项目:高并发数据查询、简单邮箱爬虫、多线程网络爬虫、python飞机大战 第三阶段-全栈前段(20) HTMP-HTML5 CSS-CSS3 JavaScript JQuerry JQuerryEasyUI jQueryMobile Bootstrap PhotoShop 第四阶段-全栈后端(35天) linux网站

  • 数据科学最终迁移到云端的5个原因

    数据科学家为企业产生洞察力提供帮助,并进行预测,以实现更明智的业务决策。以下是数据科学家应该放弃笔记本电脑或本地服务器,并将其业务迁移到云端的五个充分的理由。No1:数据科学是一项团队运动算法和机器学习模型构成了企业高级分析和机器学习难题的一部分。数据科学家、数据工程师、机器学习工程师、数据分析师和公民数据科学家都需要在这些元素上进行协作,以便为业务决策提供数据驱动的见解。No2:大数据胜过智能算法由于人们对人工智能和机器学习的兴趣激增,这是由于能够在大量结构化、非结构化和半结构化数据上快速处理和迭代(训练和调整机器学习模型)。几乎在所有情况下,机器学习都得益于在更大、更具代表性的样本集上进行训练。随着规模的扩大,数据通常需要在云端或大型内部部署集群中进行处理。将笔记本电脑添加到混合部署中会在整个流程中造成瓶颈,并导致延迟。No3:数据科学需要灵活的基础设施数据科学家可以利用许多开源机器学习框架,如R、SciKitLearn、SparkMLlib、TensorFlow、MXnet和CNTK。但是,在笔记本电脑或本地服务器上管理这些框架的基础设施、配置和环境非常麻烦。管理基础设施的额外开

  • 无服务器架构中的十大安全风险

    无服务器架构(作为服务或FaaS的功能)是应用程序在其上构建和部署后,可以根据云工作负载流自伸缩的架构。从开发的角度来看,无服务器架构主要关注核心功能,而忽略所有底层约束,如操作系统、运行时环境、存储等。无服务器架构允许开发人员只关注业务逻辑,而不关注复杂的服务器基础结构。无服务器的好处Zeroadministration—在serverless中,开发人员的工作是部署代码,而不提供计算实例、操作系统等。Auto-scaling—正如前面提到的,可以根据云工作负载动态扩展无服务器应用程序。Pay-per-use—功能即服务(functional-as-a-service,FaaS)计算和管理在使用时收费的服务,而不是预先准备的容量。很好,那么安全呢?当您使用无服务器时,供应商就是无服务器的提供者(例如:的AWSlambda、谷歌云等)负责保护所有云组件(如数据中心、网络、服务器、操作系统及其配置)然而,这只是减少了开发人员所承担的安全负担,而不是否定它。从应用程序的角度来看,应用程序开发人员仍然负责应用程序逻辑、代码、数据和应用程序层配置,使其成为共享的安全职责在服务器端引入了新的攻击

  • 中国即将面临“大数据人才荒”

    2016年9月,中国女排在里约奥运会上再次夺得世界冠军,举国欢庆。中国女排能够在极其艰难的情况下再次书写世界传奇,除了勇于拼搏的女排精神之外,科学的“数据分析”绝不可轻视。人们注意到:这次女排征战团队中,有一位身穿白色运动服,坐在球场一侧操作计算机的陪打教练——袁灵犀。此人不仅精通排球,而且懂得计算机与大数据技术。女排重金购买了专业的排球大数据分析软件,里面保存有世界排球强队每个队员在不同战术中扣球与吊球的习惯路线等资料。赛前,袁灵犀一直利用数据分析指导女排队员训练。比赛过程中,每个回合他都利用代码将有价值的细节录入系统,时时向教练提供本队与对手的技术分析数据。有了袁灵犀及其数据分析,总教练郎平才能真正做到知己知彼,正确决策,调整队员布局。大数据分析助力女排胜利夺冠,这正是大数据在中国如火如荼发展的一个缩影。 图为里约奥运会中国女排夺冠之役。光明图片/视觉中国 坐在球场边进行数据分析的袁灵犀。光明图片/视觉中国人才成掣肘大数据是新一代科技浪潮中的核心科学技术。2015年国务院印发《促进大数据发展行动纲要》,高屋建瓴地为大数据在各个领域的应用和发展提供指导。 大数据的应用发展与快速推进主

  • markdown 编辑器实现双屏同步滚动

    由于一直在使用markdown编辑器写技术文章,所以对于编写体验很敏感。我发现各大社区的markdown编辑器基本都有同步滚动功能。只不过有些做得好,有些做得马马虎虎。出于好奇,我就打算自己亲自实现一下这个功能。思考了一段时间,最后想出来了三种方案:百分比滚动双屏同时渲染占用面积大的元素每一行的元素都赋上一个索引,根据索引来精确同步每一行的滚动高度百分比滚动假设现在正在滚动a屏,那a屏的滚动百分比计算方式为:a屏的滚动高度/a屏的内容总高度,用代码表示a.scrollTop/a.scrollHeight。当滚动a屏时,需要手动同步b屏的滚动高度,也就是根据a屏的滚动百分比算出b屏的滚动高度:a.onscroll=()=>{ b.scrollTo({top:a.scrollTop/a.scrollHeight*b.scrollHeight}) }复制原理就是这么简单,可惜实现效果不太好。https://segmentfault.com/img/remote/1460000042290362从上面的动图可以看出,当我在第二个大标题处停留的时候,左右双屏的内容是同步的。但当我滚动到第三

  • 【韧性架构】韧性性工程的重要性

    韧性工程的重要性 本周AWS发生了更大的中断,当然媒体报道再次大肆报道。例如,“亚马逊网络服务中断使企业陷入困境”,华盛顿邮报的标题,仅举一个例子。你可以找到更多的媒体报道。然而,对我来说,有趣的部分并不是AWS发生了罕见的中断之一。这是大多数文章的底线:AWS发生了部分中断,因此使用AWS的公司步履蹒跚。换句话说:AWS是有罪的。这些公司是受害者。个人觉得,没那么简单。实际上,我认为AWS按承诺交付,并且确信像Netflix这样的一些公司根本不会因为这次中断而步履蹒跚。那么,其他公司做错了什么?不了解分布式系统 IMO的第一个问题是,步履蹒跚的公司对分布式系统的本质了解得不够好,无法正确评估风险。有趣的是,我刚刚在上一篇文章中描述了分布式系统的影响:跨流程边界出现问题。你无法预测什么时候会出错。它会在应用程序级别打击你。这就是您对分布式系统的基本总结。或者正如亚马逊首席技术官WernerVogels有时描述的那样:“一切都失败了,一直都是。”——维尔纳·沃格尔斯他之所以这么说,是因为AWS的人会做的很马虎。看看他们运营的系统环境的复杂性和规模以及他们经历的罕见的更大中断,他们做得非常

  • 关于老系统的重构和优化选择

      最近公司领导层脑袋发热要转java,干掉.net,所以碰到一个系统新的需求过来都要评估一下是重构还是原有的基础上修改 基于以上背景也就诞生了这篇文章:到底重构还是优化 我的建议是:工时决定一切   老系统重构会遇到2个问题:   1.业务的重新梳理   2.代码逻辑的梳理   业务的重新梳理:不用分析,大家做个系统的都明白,5年甚至10年的老系统业务梳理简直就是sheet,如果一个开发不想接这个系统,他一定会建议你去梳理业务(不用说,我就是那样的:-)) 为什么,因为要把业务梳理清楚至少要个10天半个月的,这段时间开发只要睡睡觉就能拿工资了,产品经理忙活了大半天没有沉淀文档,5年后又得重新来过。而且业务梳理是跨部门沟通,浪费的是两个部门的人的时间,算人天的话这成本可想而知。   代码逻辑的梳理:不管是重构一套还是优化,都要梳理代码逻辑,因为系统虽然重新开发的,但是老数据不能丢啊,不能升级下系统以前的数据就没了吧   重构的成本很高,那优化的成本就会很低吗?   这个要看情况,大部分情况一个优秀的程序员写的系统,优化的成本是很低的,注意,这里有个前提:优秀的程序员。我曾经碰到过企业的

  • .NET CORE——Console中使用依赖注入

    我们都知道,在ASP.NETCORE中通过依赖注入的方式来使用服务十分的简单,而在Console中,其实也只是稍微绕了个小弯子而已。不管是内置DI组件或者第三方的DI组件(如Autofac),通过IServiceCollection接口我们都可以做到和应用程序的无缝连接。本文将在别给出内置组件和第三方组件(主要是Autofac)在Console应用程序中的依赖注入实现方式。 在Console中使用内置DI组件 网上已经有几篇相关的博客讲解Console中的依赖注入,链接都会附于文章末尾。不像ASP.NETCORE在应用框架启动时便将DI容器初始化完成并且注入了大部分开发者需要的服务,我们只能从零开始。 //安装DI组件 Install-PackageMicrosoft.Extensions.DependencyInjection //安装日志输出组件 Install-PackageMicrosoft.Extensions.Logging.Console 复制 添加模拟的应用服务 publicinterfaceICounterAppService { voidCount(i

  • 博图TIA中ModbusRTU_CRC校验程序的实现

    博图TIA中ModbusRTU_CRC校验程序的实现 使用SCL语言,在博图TIA中编写ModbusRTU_CRC校验程序,使用两个FC块,实现两种不同的应用CRC1将计算结果直接输出,CRC2将计算的结果插入到输入数组的最后端. TIA中自带了modbusRTU通讯库,之所以自己实现CRC校验码的计算只是为了更深入的学习TIASCL编程序. 实现效果及代码截图 代码片段 CRC1 FUNCTION"CRC1":Void {S7_Optimized_Access:='TRUE'} VERSION:0.1 VAR_INPUT CrcData:Variant; END_VAR VAR_OUTPUT CrcValue:Word; CrcErr:Word; END_VAR VAR_TEMP Preset:Word; LoopLength:Int; ArrayPoint:Int; i:Int; ArrayLength:UDInt; Array1:Array[0..999]ofByte;//最多1000个字节 Err:Int; END_VAR BEGIN #ArrayLength:

  • 为多维数组添加一列以及reshape用法注意

    https://blog.csdn.net/orangefly0214/article/details/80934008参考这个了链接 下面是我自己用到的代码,亲测可用 #data=pd.read_csv("E:/backup_zhihu_spider/Malicious-URL-Detection-using-Machine-Learning-master/data/dataNN.csv",',',error_bad_lines=False)#readingfile#data=np.array(data)#allurl_fea=[d[0]fordindata]#x_train,y_train=get_wordvec_word(1,url_all,y_train)#我的x_train是一个三维矩阵##feature=np.c_[np.ones((x_train.shape[0],x_train.shape[1],1)),x_train]#为了与x_train拼接,先构建一个全1矩阵,前面两维与x_train一样,最后一维是最内层的维度,是1维#print(feature.shape)#

  • C# 调用外部程序Process类

    转摘自:http://www.itbobo.com/c-to-call-an-external-program-of-the-process-class.html 在程序开发中,一个程序经常需要去调用其他的程序,C#中Process类正好提供了这样的功能。它提供对本地和远程进程的访问并使您能够启动和停止本地系统进程。 一、启动进程实例 Code ProcessmyProcess=newProcess(); try { myProcess.StartInfo.UseShellExecute=false; myProcess.StartInfo.FileName="test.exe"; myProcess.StartInfo.CreateNoWindow=true; myProcess.Start(); } catch(Exceptione) { Console.WriteLine(e.Message); }复制   Process.Start方法,启动(或重用)此Process组件的StartInfo属性指定的进程资源,并将其与该组件关联。如果启动了进程资源,

  • 2020 DJBCTF RE wp

    1.anniu 吐槽:浓浓一股杂项的味道,妈的,用xspy和resourcehar加ida死活搜不到回调函数,淦 下一个灰色按钮克星,直接把灰色的按钮点亮,直接点击就可以出了,软件下载链接:http://xiazai.zol.com.cn/detail/15/147895.shtml   2. MataraOkina 这题直接反编译进去,习惯性的看manifest文件,看下主活动在哪    好家伙,果然里面藏东西呢,有些很概念,开发没用到,这里涉及到了launchMode,这个是活动的启动模式,链接如下:  https://blog.csdn.net/sinat_14849739/article/details/78072401 大概是这样的,这种2对应的singTop模式,栈顶复用,也就是意味着,当flagactivity要再次跳转到flagactivity时,很可能并不会生成新的实例,而是 仅仅更改下内容,有点ajax的味道,具体看博客吧,说的比我详细多了2333,然后就是下面的intent-filter标签,这个schem标签

  • 复习笔记——数论

    素数 线性筛 每个合数被最小质因子筛掉 用线性筛可求\(phi\)、\(mu\)等积性函数 intp[N],prime[N],pnum; voidgetp(){ for(inti=2;i<N;i++)p[i]=1; for(inti=2;i<N;i++){ if(p[i])prime[pnum++]=i; for(intj=0;j<pnum&&1ll*i*prime[j]<N;j++){ p[prime[j]*i]=1; if(i%prime[j]==0)break; } } } 复制 试除法判断素数 用2~\(\sqrt{n}\)试除 boolisprime(intx){ for(inti=2;i*i<=x;i++) if(x%i==0)returnfalse; returntrue; } 复制 Miller-Rabin素性测试 Pollard-Rho分解质因数 最大公约数 最大公约数与最小公倍数 辗转相除法 intgcd(inta,intb){returnb?gcd(b,a%b):a;} 复制 \(lcm(a,b)=\frac{ab}

  • P1606 [USACO07FEB]Lilypad Pond G

    显然的最短路计数,但因为是求增加莲花的数量,跳到水格子代价为\(1\),跳到莲花格子代价为\(0\),所以要先暴力处理出每个水格子不放置莲花能到达的所有水格子并直接建边,这样就消去了边权为\(1\)的边。 注意将起点和终点均视为水格子,最终答案要减一。

  • springboot启动流程分析

    https://www.cnblogs.com/hello-shf/p/10976646.html

  • 出现java.lang.IllegalArgumentException异常

      严重:Servlet.service()forservlet[office]incontextwithpath[/office]threwexception[Requestprocessingfailed;nestedexceptionisjava.lang.IllegalArgumentException:classcom.office.Entity.BusinessBuildManagerdeclaresmultipleJSONfieldsnamedtoward_direction]withrootcausejava.lang.IllegalArgumentException:classcom.office.Entity.BusinessBuildManagerdeclaresmultipleJSONfieldsnamedtoward_direction atcom.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.jav

  • 字符串操作

    ————ostrstream&istrstream类流复制 ostrstream实现将一个二进制数转换成串的字符存于字符数组对象中复制 istrstream流可以实现将一个字符串的数字字符转换成二进制形式存入在某种类型的对象中。 istrstream流为流对象提供了两种构造函数,它们的原型分别是: 复制 1.istrstream::istrsteam(char*s)复制 2.istrstream::istrstream(char*s,intn)复制 例:charbuffer1[100]="1010.1";   charbuffer1[100]="10.1";   doublem,n;   inti;   istrstreamstr(buffer1);   str>>i>>m;   istrstreamstr(buffer2,2);  &n

  • 过去的事情不要轻易提及

    过去的事情不要轻易提及。 谈论过去,要么是谈到过往的成绩,产生我慢;要么是谈到自己或者别人的过失过错,产生嗔心。 总之,谈到过去,最容易“自是他非”。 很少的时候,谈到过去,是谈“自非”。 更少的时候,谈到过往,是谈“他是”,很少去专门谈别人过去对你的好,对你的恩情。 人要向前看,专注现在,专注今天,今天如何过得快乐而充实。 老是念及过往,或者幻想未来,今天是不可能过得快乐充实平和的。

相关推荐

推荐阅读